Cecile Fauvelot has kindly shared a giant (n=1358) microsatellite dataset for Dascyllus aruanus, the white tailed or humbug damsel. We don’t have an empirical parentage kernel for this species, but she does have samples from New Caledonia and Fiji which are two of the archipelagos in our proposal. She also has them from French Polynesia and Papua New Guinea. So the goal here is to do a preliminary analysis for the sake of the proposal. One problem will be that these are likely adults, not new recruits…

White Tailed Damsel

Sample Sites

Read and convert data

Had to do a little conversion in bbedit to ready the Excel formatted data for input into R

Read in the data

#read in the data
Daruanus.gen <- read.genepop("Daruanus_Fauvelot.gen", ncode = 3L)

 Converting data from a Genepop .gen file to a genind object... 


File description:  Dascyllus aruanus all populations 1358 individuals 

...done.
# rename the populations to just the text values
Daruanus.gen@pop <- Daruanus.gen@pop %>% str_extract("[A-Za-z]+") %>% as.factor()

# read in the locality information
Daruanus.sites <- read_excel("Daruanus_sites.xlsx")

Daruanus.gen@pop %>% tibble(pop = as.character(.)) %>% count(pop)
NA

Test for HWE

Test for HWE. First look at the number of populations that have HWE departures for each locus. Then look at the distribution of p-values following (Waples 2014). A flat distribution is fine, but enrichment for low p-values suggests that the locus is not globally at HWE.


separated_pops <- seppop(Daruanus.gen)

# perform HWE test
hw <- map(separated_pops, hw.test)
 
hw2 <- do.call(rbind,hw) %>% as_tibble(rownames = "locus") %>%  group_by(locus) %>%
        summarize(outofhwe = length(which(Pr.exact < 0.05)), 
                  outofhwe_prop = length(which(Pr.exact < 0.05))/length(hw),
                  meanp = mean(Pr.exact))

hw2


pvalues<- do.call(rbind,hw) %>% as_tibble(rownames = "locus") %>%  group_by(locus) %>% 
          ggplot(aes(x=Pr.exact)) + geom_histogram(bins=10) + facet_wrap(~locus)

pvalues

It’s pretty clear we need to zap loci 408, 494, and 593. 565 is a little weird, but let’s keep it.

locNames(Daruanus.gen)
 [1] "304" "408" "331" "589" "494" "523" "360" "565" "542" "593" "590"
Daruanus.gen <- Daruanus.gen[loc=-c(2,5,10)]

#convert to strataG gtypes
Daruanus.gtypes <- genind2gtypes(Daruanus.gen)

#genind_to_genepop(Daruanus.gen, output = "Daruanus/Daruanus_All_8locus.txt")

Split by Archipelago

#split them again
separated_pops <- seppop(Daruanus.gen)

#split off the Fiji samples
fijipops <- Daruanus.sites %>% filter(Region=="Fiji")
Daruanus.Fiji <- repool(separated_pops[fijipops$Abbr])

#split off the NC samples
NCpops <- Daruanus.sites %>% filter(Region=="NC") %>% filter(Abbr!="Hie")
Daruanus.NC <- repool(separated_pops[NCpops$Abbr])

#split off the FP samples
FPpops <- Daruanus.sites %>% filter(Region == "FP") %>% 
  filter(Abbr %in% c("Puna","Tetia", "Tem","Mo","Tahaa"))
Daruanus.FP <- repool(separated_pops[FPpops$Abbr])




#genind_to_genepop(Daruanus.NC,output = "Daruanus/NC/Daruanus_NC.txt")
#genind_to_genepop(Daruanus.Fiji,output = "Daruanus/Fiji/Daruanus_Fiji.txt")
#genind_to_genepop(Daruanus.FP,output = "Daruanus/FP/Daruanus_FP.txt")

Calculate Effective Size

Neel et al. (2013) say:

Our results show that the LD method provides a good approximation of the NS as long as the scale of sampling is commensurate with the scale of local breeding.

Treating the whole dataset as one population yields \(N_e\) of -27423.9 (in other words too large) at pcrit of 0.02. But the problem is determining the size of the genetic neighborhood, because Fauvelot et al.’s samples were not as regularly spaced as D’Aloia’s.

Going to use the LD method as most recently discussed by Waples and Do (2010), and implemented in NeEstimator v2 (Do et al. 2014). I’m going to remove alleles following Waples and Do’s rule of thumb. Parameter settings are in "Daruanus/Ne_estimator/" Best to run this from the command line actually. I am having it calculate \(N_b\) (number of breeders) for monogamy, as the protogynous mating system of Dascyllus aruanus seems closer to monogamy than random mating. Also had to edit the table output of NeEstimator to make it legible to R because it had lots of spaces and empty cells 👎

/Applications/NeEstimator/Ne2-1M i:/Users/eric/github/IBD_Kernels/Daruanus/NeEstimator/info o:/Users/eric/github/IBD_Kernels/Daruanus/NeEstimator/option

INFO
1   * A number = sum of method(s) to run: LD(=1), Het(=2), Coan(=4), Temporal(=8).
/Users/eric/github/IBD_Kernels/Daruanus/    * Input Directory
Daruanus_All_8locus.txt * Input file name
2           * 1 = FSTAT format, 2 = GENEPOP format
/Users/eric/github/IBD_Kernels/Daruanus/NeEstimator/    * Output Directory
Daruanus_LDNe.txt   * Output file name (put asterisk adjacent to the name to append)
6           * Number of critical values, added 1 if a run by rejecting only singleton alleles is included
1 0.01 0.02 0.03 0.04 0.05      * Critical values, a special value '1' is for rejecting only singleton alleles
1       * 0: Random mating, 1: Monogamy (LD method)


OPTION
1  1  5  1  * First number = sum of method(s) to have extra output: LD(=1), Het(=2), Coan(=4), Temporal(=8)
0   * Maximum individuals/pop. If 0: no limit
0   * First entry n1 = 0: No Freq output. If n1 = -1: Freq. output up to population 50. Two entries n1, n2 with n1 <= n2: Freq output for populations from n1 to n2. Max. populations to have Freq output is set at 50
0   * For Burrow output file (up to 50 populations can have output). See remark below
1   * Parameter CI: 1 for Yes, 0 for No
1   * Jackknife CI: 1 for Yes, 0 for No
0   * Up to population, or range of populations to run (if 2 entries). If first entry = 0: no restriction
0   * All loci are accepted
1   * Enter 1: A file is created to document missing data if there are any in input file. Enter 0: no file created
0   * Line for chromosomes/loci option and file

I implemented a filtering step that follows Waples and Do (2010) :

For S > 100: choose Pcrit = 0.01 For S > 25: choose Pcrit = 0.02.
For S < 25: choose so that 1/(2S) < Pcrit < 1/S.

And I am only keeping estimates from samples with n >= 10.

Ne_estimates <- read_NeEstimator(file = "./NeEstimator/Daruanus_LDNe_xLD.txt")
Warning: 248 parsing failures.
row            col               expected   actual                                  file
  1 ParametricHigh no trailing characters Infinite './NeEstimator/Daruanus_LDNe_xLD.txt'
  1 JackknifeHigh  no trailing characters Infinite './NeEstimator/Daruanus_LDNe_xLD.txt'
  2 ParametricHigh no trailing characters Infinite './NeEstimator/Daruanus_LDNe_xLD.txt'
  2 JackknifeHigh  no trailing characters Infinite './NeEstimator/Daruanus_LDNe_xLD.txt'
  3 ParametricHigh no trailing characters Infinite './NeEstimator/Daruanus_LDNe_xLD.txt'
... .............. ...................... ........ .....................................
See problems(...) for more details.
# filtering based on rule of thumb from Waples & Do
Ne_estimates_f <- WDFilter(Ne_estimates, 10) %>% 
  mutate(Population = str_replace(Population,pattern = "\\d+\\:(\\w+)_[\\w-]+", replacement = "\\1" ))

Interpreting LD Effective Size

These estimates are true Ne estimates because these samples were taken across the age structure of the population. So there won’t be any conversion from Nb to Ne.

Cecile says: > For Fiji and NC, multiple individuals at a coral colony were indeed sampled as we used clove oil around coral colonies covered by a plastic bag… so yes too, across age structure. I do not have the size of individuals sampled

(Waples, Antao, and Luikart 2014) says:

Our empirical results provide some qualified support for the hypothesis (Waples and Do 2010) that a sample that includes as many cohorts as there are in a generation should produce an estimate approximately equal to Ne….All estimates based on random samples of adults were smaller than true Ne …, but there was a tendency for the bias to be less when the number of cohorts included in the adult sample corresponded more closely to the generation length.

Dascyllus aruanus strikes me as one of those species where you’ll have as many cohorts as generations, although protogyny kind of messes with this. In any case, we can expect our estimates of Ne (and thus De) to be downwardly biased, and therefore our estimates of \(\sigma\) to be upwardly biased, by hopefully less than 10%?

New Caledonia

Traditional Isolation by Distance Method

Based on the OG (Rousset 1997) estimator from slope of the IBD regression.

Calculate distance matrices

Weir and Cockerham’s Fst and other basic stats


Daruanus.NC.hfst <- genind2hierfstat(Daruanus.NC)
Daruanus.NC.loci <- genind2loci(Daruanus.NC)
#gen.loci <- genind2loci(gen)
stats.NC <- basic.stats(Daruanus.NC)
theta.NC <- theta.msat(Daruanus.NC.loci)
#mean theta
mean(theta.NC[,2])
[1] 156.622
fst.NC <- genet.dist(Daruanus.NC.hfst, method = "WC84")
# mean Fis values
stats.NC$Fis %>% as_tibble() %>% summarize(across(everything(),mean, na.rm=TRUE))

meanFis <- stats.NC$Fis %>% as_tibble() %>% summarize(across(everything(),mean, na.rm=TRUE)) %>% summarize(meanFis = rowMeans(.))
# linearize
fst.NC <- fst.NC/(1-fst.NC)


#calculate great circle distance
gcdists_NC <- as.dist(pointDistance(NCpops[,5:4], lonlat=T)/1000)
attr(gcdists_NC, "Labels") <- NCpops$Abbr
gcdists.mat_NC <- as.matrix(gcdists_NC)
#write.csv(as.matrix(gen.fst), "Daruanus_linearizedFst.csv", row.names = F, quote=F)
#write.csv(as.matrix(gcdists), "Daruanus_gcdists.csv", row.names = F, quote=F)

#pull out a few other distances we'll need
neighbordists_NC <- gcdists.mat_NC[row(gcdists.mat_NC) == col(gcdists.mat_NC) + 1]
distfromP1_NC <- gcdists.mat_NC[,1]
maxdist_NC <- max(gcdists.mat_NC)
meandists_NC <- mean(neighbordists_NC)

Create Dispersal Kernel

Calculate linear model

First to get the slope \(m\) we need to make a simple linear model. I don’t think significance is really important here, but we can calculate that with a Mantel test.

# mantel test
mantelt <- mantel.randtest(fst.NC,gcdists_NC, nrepet = 10000)

distances <- tibble(distance=as.vector(gcdists_NC),fst=as.vector(fst.NC))

lmodel_NC <- lm(fst ~ distance , distances)

slope_NC <- round(lmodel_NC$coefficients[2],7)
mantelr <- round(mantelt$obs, 2)
pvalue <- round(mantelt$pvalue, 5)

lmodel_plot_NC <- ggplot(distances,aes(x=distance,y=fst)) +
                geom_point() + geom_smooth(method=lm) + xlab("Geographic Distance (km)") + 
                ylab(expression(F["ST"]/1-F["ST"])) + 
                geom_text(label = paste("m =", slope_NC, 
                                        "; Mantel r =", mantelr,
                                        ", p =", pvalue ), 
                          mapping = aes(x = 80, y = -0.002))

lmodel_plot_NC
`geom_smooth()` using formula 'y ~ x'

#ggsave("NC_IBD.pdf", plot=clown_plot,device="pdf", width=7, height=5,units="in")

Yowza. Negative slope! As Cecile had already measured. But the Fst values are really teeny.

Calculate Effective Size

Take the harmonic mean of the Ne across all pops

Ne_estimates_NC <- Ne_estimates_f %>% filter(Population %in% NCpops$Abbr)

#write_csv(Nb_estimates_f,"NeEstimator/Nb_estimates_recruits_NeTable.csv")
Ne_estimates_NC[,c(1:4,8,11,12)]

# harmonic mean of Nb, following Waples and Do 2010
Ne_hm_NC <- harm_mean(Ne_estimates_NC$Ne)

Ne vs. Sampling Window

Let’s cluster the sites by UPGMA

plot(hclust(gcdists_NC,"average"))

10km

Let’s explore Ne and Fis when lumping populations… First lump populations that are less than 10 km apart

stats.NC$Fis %>% as_tibble() %>% summarize(across(everything(),mean, na.rm=TRUE))

Daruanus.NC.10km <- Daruanus.NC

Daruanus.NC.10km@pop <-  Daruanus.NC.10km@pop %>% fct_collapse(
   center = c("Go","Lar"),
 )

Daruanus.NC.10km.stats <- basic.stats(Daruanus.NC.10km)

Daruanus.NC.10km.stats$Fis %>% as_tibble() %>% summarize(across(everything(),mean, na.rm=TRUE))

meanFis_NC_10km <- Daruanus.NC.10km.stats$Fis %>% as_tibble() %>% summarize(across(everything(),mean, na.rm=TRUE)) %>% 
  summarize(meanFis = rowMeans(.))

#genind_to_genepop(Daruanus.NC.10km,output = "Daruanus/NC/Daruanus_NC_10km.txt")

Ne_estimates_NC10km <- read_NeEstimator(
                        "NeEstimator/Daruanus_LDNe_NC_10kmxLD.txt")
Warning: 52 parsing failures.
row            col               expected   actual                                       file
  1 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_10kmxLD.txt'
  1 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_10kmxLD.txt'
  2 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_10kmxLD.txt'
  2 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_10kmxLD.txt'
  3 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_10kmxLD.txt'
... .............. ...................... ........ ..........................................
See problems(...) for more details.
Ne_estimates_NC10km <- WDFilter(Ne_estimates_NC10km, 10)


Ne_hm_NC10km <- harm_mean(Ne_estimates_NC10km$Ne)

20km

Now move up to 20 km

Daruanus.NC.20km <- Daruanus.NC

Daruanus.NC.20km@pop <-  Daruanus.NC.20km@pop %>% fct_collapse(
   center = c("MBO","Lar","Go","QBW")
 )

Daruanus.NC.20km.stats <- basic.stats(Daruanus.NC.20km)

Daruanus.NC.20km.stats$Fis %>% as_tibble() %>% summarize(across(everything(),mean, na.rm=TRUE))
meanFis_NC_20km <- Daruanus.NC.20km.stats$Fis %>% as_tibble() %>%
  summarize(across(everything(),mean, na.rm=TRUE)) %>% summarize(meanFis = rowMeans(.))

#genind_to_genepop(Daruanus.NC.20km,output = "NC/Daruanus_NC_20km.txt")

Ne_estimates_NC20km <- read_NeEstimator(file = "NeEstimator/Daruanus_LDNe_NC_20kmxLD.txt")
Warning: 39 parsing failures.
row            col               expected   actual                                       file
  1 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_20kmxLD.txt'
  1 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_20kmxLD.txt'
  2 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_20kmxLD.txt'
  2 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_20kmxLD.txt'
  3 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_20kmxLD.txt'
... .............. ...................... ........ ..........................................
See problems(...) for more details.
Ne_estimates_NC20km <- WDFilter(Ne_estimates_NC20km, 10)

Ne_hm_NC20km <- harm_mean(Ne_estimates_NC20km$Ne)

40km

Now move up to 40 km

Daruanus.NC.40km <- Daruanus.NC

Daruanus.NC.40km@pop <-  Daruanus.NC.40km@pop %>% fct_collapse(
   north = c("Mara","Ten"),
   center = c("MBO","Lar","Go","QBW")
 )

Daruanus.NC.40km.stats <- basic.stats(Daruanus.NC.40km)

Daruanus.NC.40km.stats$Fis %>% as_tibble() %>% summarize(across(everything(),mean, na.rm=TRUE))

meanFis_NC_40km <- Daruanus.NC.40km.stats$Fis %>% as_tibble() %>%
  summarize(across(everything(),mean, na.rm=TRUE)) %>% summarize(meanFis = rowMeans(.))

#genind_to_genepop(Daruanus.NC.40km,output = "NC/Daruanus_NC_40km.txt")

Ne_estimates_NC40km <- read_NeEstimator(file = "NeEstimator/Daruanus_LDNe_NC_40kmxLD.txt")
Warning: 29 parsing failures.
row            col               expected   actual                                       file
  1 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_40kmxLD.txt'
  1 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_40kmxLD.txt'
  2 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_40kmxLD.txt'
  2 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_40kmxLD.txt'
  3 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_40kmxLD.txt'
... .............. ...................... ........ ..........................................
See problems(...) for more details.
Ne_estimates_NC40km <- WDFilter(Ne_estimates_NC40km, 10)

Ne_hm_NC40km <- harm_mean(Ne_estimates_NC40km$Ne)

100km

Now move up to 100 km

Daruanus.NC.100km <- Daruanus.NC

Daruanus.NC.100km@pop <-  Daruanus.NC.100km@pop %>% fct_collapse(
  north = c("Mara"),
  east = c("MBO","Lar","Go","QBW","Tote","Ten")
 )

Daruanus.NC.100km.stats <- basic.stats(Daruanus.NC.100km)

Daruanus.NC.100km.stats$Fis %>% as_tibble() %>% summarize(across(everything(),mean, na.rm=TRUE))

meanFis_NC_100km <- Daruanus.NC.100km.stats$Fis %>% as_tibble() %>%
  summarize(across(everything(),mean, na.rm=TRUE)) %>% summarize(meanFis = rowMeans(.))



#genind_to_genepop(Daruanus.NC.100km,output = "NC/Daruanus_NC_100km.txt")

Ne_estimates_NC100km <- read_NeEstimator(file =
                                             "NeEstimator/Daruanus_LDNe_NC_100kmxLD.txt")
Warning: 22 parsing failures.
row            col               expected   actual                                        file
  1 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_100kmxLD.txt'
  1 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_100kmxLD.txt'
  2 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_100kmxLD.txt'
  2 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_100kmxLD.txt'
  3 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_100kmxLD.txt'
... .............. ...................... ........ ...........................................
See problems(...) for more details.
Ne_estimates_NC100km <- WDFilter(Ne_estimates_NC100km, 10)

#replace one very large estimate of Ne with 20,0000
Ne_estimates_NC100km$Ne[1] <- 20000

Ne_hm_NC100km <- harm_mean(Ne_estimates_NC100km$Ne)

200km

Now move up to 200 km (all pops as one)

Ne_estimates_NC200km <- read_NeEstimator(file =
                                             "NeEstimator/Daruanus_LDNe_NC_1popxLD.txt")
Warning: 10 parsing failures.
row            col               expected   actual                                       file
  1 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_1popxLD.txt'
  1 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_1popxLD.txt'
  2 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_1popxLD.txt'
  2 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_1popxLD.txt'
  3 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_NC_1popxLD.txt'
... .............. ...................... ........ ..........................................
See problems(...) for more details.
Ne_estimates_NC200km <- WDFilter(Ne_estimates_NC200km, 10)



Ne_hm_NC200km <- Ne_estimates_NC200km$Ne
Ne_all_NC <- Ne_estimates_NC200km$Ne

Ne_all_NC_CI <- c(Ne_estimates_NC200km$ParametricLow,Ne_estimates_NC200km$ParametricHigh)

Figure

NCwindows <- tibble(SampleWindow = c(0,10,20,40,100,200),
                      hm_Ne = c(Ne_hm_NC,Ne_hm_NC10km,Ne_hm_NC20km,Ne_hm_NC40km,
                                Ne_hm_NC100km,Ne_hm_NC200km))

ggplot(NCwindows, aes(x = SampleWindow, y = hm_Ne)) + geom_point() + geom_line() +
  ylim(0,20000) + xlim(0,300)

#ggsave("NC_Ne_v_SampDistance.pdf",height = 7, width = 7)

Calculate Effective Density

# Divide by mean distance between sampling sites to get density
De_NC <- Ne_hm_NC/meandists_NC
De_all_NC <- Ne_all_NC / maxdist_NC

Mean density is 32.6102505 individuals/km, or if we do the whole sample as a single population 41.9068643 individuals/km

MigraiNe Method

Running MigraiNe

I modified the genepop file by adding sampling coordinates as the name of the last individual in each population. These coordinates were distances in km along a the mostly linear SW coastline of New Caledonia, which runs a total of ~612km. It is ~418km to the first population at Mara, so I am adding that value to the coordinates in the file.

distfromP1_NC+418
    Mara      Ten      MBO      Lar       Go      QBW     Tote 
418.0000 454.7026 494.1474 507.2045 514.9837 527.4177 568.2117 

First Run

GenepopFileName=../Daruanus_NC.txt
DemographicModel=LinearIBD
# I modified the genepop file by adding sampling coordinates as the name of the 
# last individual in each population. These coordinates were distances in km along 
# a the mostly linear SW coastline of New Caledonia, 
# which runs a total of ~612km. It is ~418km to the first population at Mara, 
# so I am adding that value to the coordinates in the file.
PSONMax=612 0
#Neighborhood size is based on mean distance between populations = 25.08
#612/25.08 = 24.40 so I will use 25 bins
GeoBinNbr=25
GeoUnit= ind.km
#alternate way of specifying the habitat, not used for now
#habitatPars= 0.5 0.5 400 1 0
#habitatPars=0 0 0 300 0
#Mutation Model is K-allele = PIM, with k=2 for SNPs. GivenK is number of alleles
# at each locus
MutationModel=PIM
GivenK=26,35,11,57,47,32,30,23,57,34,44
samplingSpace=,,
samplingScale=,,
#Analysis - this will do 5 runs of 100 points and
#overwrite those with 10 runs of 250 points
writeSequence= Over,Over,Over,Over,Over,Append,10
StatisticSequence=PAC
PointNumber=100,100,100,100,100,250
Nrunsperpoint=30,30,30,30,30,50
#Wide priors on Neu, Nem and g
LowerBound=0.1,1,0
Upperbound=1,2500,1
oneDimCI= 2Nmu, 2Nm, Nb, condS2
CoreNbrForR=4
#Plots= all1DProfiles
1DProfiles=2Nmu, 2Nm, Nb, condS2, g
extrascale=Nb=logscale
graphicFormat=pdf
#writeAdHocFiles=T

And wow, that first run completed in 219 minutes with a reasonable result, so I think I’m just going to use it for now. It didn’t calculate or plot condS2 though…

Second Run

GenepopFileName=../Daruanus_NC.txt
DemographicModel=LinearIBD
# I modified the genepop file by adding sampling coordinates as the name of the 
# last individual in each population. These coordinates were distances in km along 
# a the mostly linear SW coastline of New Caledonia, 
# which runs a total of ~612km. It is ~418km to the first population at Mara, 
# so I am adding that value to the coordinates in the file.
PSONMin=0 0
PSONMax=612 0
#Neighborhood size is based on mean distance between populations = 25.08
#612/25.08 = 24.40 so I will use 26 bins
GeoBinNbr=26
GeoUnit= ind.km
#alternate way of specifying the habitat, not used for now
#habitatPars= 0.5 0.5 400 1 0
#habitatPars=0 0 0 300 0
#Mutation Model is K-allele = PIM, with k=2 for SNPs
MutationModel=PIM
GivenK=26,35,11,57,47,32,30,23,57,34,44
samplingSpace=,,
samplingScale=,,
#Analysis - this will do 5 runs of 100 points and
#overwrite those with 10 runs of 250 points
writeSequence= Over,Over,Over,Over,Over,Append,10
StatisticSequence=PAC
PointNumber=100,100,100,100,100,250
Nrunsperpoint=30,30,30,30,30,50
#Wide priors on Neu, Nem and g
LowerBound=0.1,1,0
Upperbound=2,10000,1
oneDimCI= 2Nmu, 2Nm, Nb, condS2
CoreNbrForR=4
#Plots= all1DProfiles
1DProfiles=2Nmu, 2Nm, Nb, condS2, g
extrascale=Nb=logscale
graphicFormat=pdf
#writeAdHocFiles=T

This finished in 250 minutes, and had very similar results to the first run

Third Run

After removing 3 loci

GenepopFileName=../../Daruanus_NC.txt
DemographicModel=LinearIBD
# I modified the genepop file by adding sampling coordinates as the name of the 
# last individual in each population. These coordinates were distances in km along 
# a the mostly linear SW coastline of New Caledonia, 
# which runs a total of ~612km. It is ~418km to the first population at Mara, 
# so I am adding that value to the coordinates in the file.
PSONMin=0 0
PSONMax=612 0
#Neighborhood size is based on mean distance between populations = 25.08
#612/25.08 = 24.40 so I will use 25 bins
GeoBinNbr=25
GeoUnit= ind.km
#alternate way of specifying the habitat, not used for now
#habitatPars= 0.5 0.5 400 1 0
#habitatPars=0 0 0 300 0
#Mutation Model is K-allele = PIM, with k=2 for SNPs
MutationModel=PIM
GivenK=26,11,57,32,30,23,57,44
samplingSpace=,,
samplingScale=,,
#Analysis - this will do 5 runs of 100 points and
#overwrite those with 10 runs of 250 points
writeSequence= Over,Over,Over,Over,Over,Append,10
StatisticSequence=PAC
PointNumber=100,100,100,100,100,250
Nrunsperpoint=30,30,30,30,30,50
#Wide priors on Neu, Nem and g
LowerBound=0.1,1,0
Upperbound=2,10000,1
oneDimCI= 2Nmu, 2Nm, Nb, condS2
CoreNbrForR=4
Plots= all1DProfiles
#1DProfiles=2Nmu, 2Nm, Nb, condS2, g
extrascale=Nb=logscale
graphicFormat=pdf
#writeAdHocFiles=T

Fourth Run

And, lo, I forgot to use the condS2 parameterization that is recommended for weak IBD signals by Leblois and Rousset (2020)!

GenepopFileName=../../Daruanus_NC.txt
DemographicModel=LinearIBD
# I modified the genepop file by adding sampling coordinates as the name of the 
# last individual in each population. These coordinates were distances in km along 
# a the mostly linear SW coastline of New Caledonia, 
# which runs a total of ~612km. It is ~418km to the first population at Mara, 
# so I am adding that value to the coordinates in the file.
PSONMin=0 0
PSONMax=612 0
#Neighborhood size is based on mean distance between populations = 25.08
#612/25.08 = 24.40 so I will use 25 bins
GeoBinNbr=25
GeoUnit= ind.km
#alternate way of specifying the habitat, not used for now
#habitatPars= 0.5 0.5 400 1 0
#habitatPars=0 0 0 300 0
#Mutation Model is K-allele = PIM, with k=2 for SNPs
MutationModel=PIM
GivenK=26,11,57,32,30,23,57,44
#sampling - this performs uniform sampling of ln(sigma^2), which is the quantity we are interested in
samplingSpace=,,condS2
samplingScale=,,logscale
#Analysis - this will do 5 runs of 100 points and
#overwrite those with 10 runs of 250 points
writeSequence= Over,Over,Over,Over,Over,Append,10
StatisticSequence=PAC
PointNumber=100,100,100,100,100,250
Nrunsperpoint=30,30,30,30,30,50
#Wide priors on Neu, Nem and g
LowerBound=0.1,1,1
Upperbound=2,10000,100000
oneDimCI= 2Nmu, 2Nm, Nb, condS2
CoreNbrForR=4
Plots= all1DProfiles
#1DProfiles=2Nmu, 2Nm, Nb, condS2, g
extrascale=Nb=logscale
graphicFormat=pdf
#writeAdHocFiles=T

Finishing in 171.6 minutes

Seventh Run

Brought in the priors a little. Didn’t change the results much.

GenepopFileName=../../Daruanus_NC.txt
DemographicModel=LinearIBD
# I modified the genepop file by adding sampling coordinates as the name of the 
# last individual in each population. These coordinates were distances in km along 
# a the mostly linear SW coastline of New Caledonia, 
# which runs a total of ~612km. It is ~418km to the first population at Mara, 
# so I am adding that value to the coordinates in the file.
PSONMin=0 0
PSONMax=612 0
#Neighborhood size is based on mean distance between populations = 25.08
#612/25.08 = 24.40 so I will use 26 bins
GeoBinNbr=26
GeoUnit= ind.km
#alternate way of specifying the habitat, not used for now
#habitatPars= 0.5 0.5 400 1 0
#habitatPars=0 0 0 300 0
#Mutation Model is K-allele = PIM, with k=2 for SNPs
MutationModel=PIM
GivenK=26,11,57,32,30,23,57,44
#sampling - this performs uniform sampling of ln(sigma^2)
samplingSpace=,,condS2
samplingScale=,,logscale
#Analysis - this will do 5 runs of 100 points and
#overwrite those with 10 runs of 250 points
writeSequence= Over,Over,Over,Over,Over,Append,10
StatisticSequence=PAC
PointNumber=100,100,100,100,100,250
Nrunsperpoint=30,30,30,30,30,50
#Wide priors on Neu, Nem and conds2
LowerBound=0.1,1,1
Upperbound=2,6000,10000
oneDimCI= 2Nmu, 2Nm, Nb, condS2, g
#oneDimCI= All
CoreNbrForR=4
Plots= all1DProfiles
#1DProfiles=2Nmu, 2Nm, Nb, condS2, g
extrascale=Nb=logscale
graphicFormat=pdf
writeAdHocFiles=T

Finished in 187.55 minutes.

Create Dispersal Kernels

Sigma estimates

So we have two routes to estimate \(\sigma\) here.

From Neighborhood Size

\[ \sigma = \sqrt\frac{NS}{4D_e} \]

Using the estimate of neighborhood size and the above derived estimate of \(D_e\), \(\sigma\) is 227km.

From Sigma^2

After converting it from lattice units to km

\[ \sigma = \sqrt{\sigma^2} \]

This got me the following estimates.

Output from run 7.

runDir <- "/Users/eric/github/IBD_Kernels/Daruanus/NC/Migraine/run7"
#runDir <- "/Users/edc5240/github/IBD_Kernels/Daruanus/NC/Migraine/run7"
result <- read_migraine(runDir)
Read 20 items
NS_NC <- result["NS"]
NSCI_NC <- c(result["NSCI1"],result["NSCI2"])
Nmu_NC <- result["Nmu"]
Nm_NC <- result["Nm"]
g_NC <- result["g"]
lattice2geog_NC <- result["lattice2geog"]

sigma2_NC <- g_to_sigma2(g_NC)
sigma_fromsigma2_NC <- sqrt(sigma2_NC*lattice2geog_NC)
sigma_fromNS_NC <- sqrt(NS_NC/(4*De_NC))
sigmaCI_fromNS_NC <- sqrt(NSCI_NC/(4*De_NC))

sigma_fromNS_all_NC <- sqrt(NS_NC/(4*De_all_NC))
sigmaCI_fromNS_all_NC <- sqrt(NSCI_NC/(4*De_all_NC))

The \(\sigma\) we get from Neighborhood Size \(\sigma\) is 226.7921311. We get a much lower estimate from \(\sigma^2\), with \(\sigma\) = 1747.5354074

Confidence Intervals

Propagating error sorta following Pinsky et al. table S2

Error in Effective Size

Following Pinsky, Montes, and Palumbi (2010) I am going to bootstrap across the confidence intervals for each Nb estimate. Unfortunately, the new jackknife method of Jones, Ovenden, and Wang (2016) often results in infinite upper bounds with marine data (but then, so does the parametric method). I’m also going to use a uniform distribution for the error because approximating the error structure with ChiSq or Normal distributions is not a simple task and I’m just trying to get a sketch of the error to compare with MigraiNe anyway. I’m going to set “Infinite” values in the upper CI to 20,000 since I rarely see upper bounds that high.

For Harmonic Mean Method
Ne_estimates_NC$JackknifeHigh[which(is.na(Ne_estimates_NC$JackknifeHigh))] <- 20000
Ne_estimates_NC$JackknifeHigh <- as.numeric(Ne_estimates_NC$JackknifeHigh)
Ne_estimates_NC$JackknifeLow <- as.numeric(Ne_estimates_NC$JackknifeLow)

# couldn't get purrr:map to do this, so resorted to mapply to set upper and lower bounds
Ne_error_NC <- NULL
for(n in 1:100000){
  hm <- harm_mean(mapply(runif, n=1, 
                   min=Ne_estimates_NC$JackknifeLow,
                   max=Ne_estimates_NC$JackknifeHigh))
  Ne_error_NC <- c(Ne_error_NC,hm)
}
names(Ne_error_NC)<-NULL

ggplot(data = tibble(Ne_error_NC), aes(x=Ne_error_NC)) + geom_density()

For Whole Sample Method

Naaykens and D’Aloia showed that using the whole sample to estimate density gives pretty similar results to the harmonic mean method, so I’m also going to try that.

Nbl95 <- Ne_all_NC_CI[1]
Nbu95 <- Ne_all_NC_CI[2]
Nb <- Ne_all_NC
r2_NC <- Ne_estimates_NC200km$r2
er2_NC <- 1/Ne_estimates_NC200km$SampSize + 3.19/Ne_estimates_NC200km$SampSize ^2 #from Waples 2006 table 2
df_NC <- Ne_estimates_NC200km$IndAlleles
#effDF is the degrees of freedom to get the jackknife CI!
# This method of finding DF makes no sense. Not sure how Malin got this to work
# a2 = 100000
# a1 = 100
# while(abs(mean(as.numeric(a1))-a2) > 1){ 
#   if(mean(as.numeric(a1)) > a2) a2 = a2 - 1
#   if(mean(as.numeric(a1)) < a2) a2 = a2 + 1
#   a1 = c(Nbl95, Nbu95)*qchisq(c(0.975, 0.025), df=a2)/Nb
# }
# a2 #df

WaplesMonoNe(r2p(r2_NC,er2_NC))
[1] 6140.55
# this shows that we can get approximately what NeEstimator gives us... not sure why its not exact... must be missing some correction
rCI_NC <- df_NC*r2_NC / (qchisq(c(0.025,0.975), df = df_NC))
WaplesMonoNe(rCI_NC - er2_NC)
[1]  3729.688 16288.111
#and now to get and plot the error distribution
Ne_error_all_NC <- WaplesMonoNe(((df_NC*r2_NC)/(rchisq(10000, df = df_NC))) - er2_NC)

ggplot(data = tibble(Ne_error_all_NC), aes(x=Ne_error_all_NC)) + geom_density() + xlim(0,20000)
Warning: Removed 150 rows containing non-finite values (stat_density).

NA

Error in Effective Density

One issue with this analysis is that, while Neel et al. (2013) make a good case that we are estimating the Ne of the local neighborhood, we don’t actually know what the size of the neighborhood is. Indeed, that’s actually what we are trying to estimate. (Pinsky, Montes, and Palumbi 2010) used neighborhoods that were 1/2 the distance to the next neighborhood on either side of the sampling site, while (Pinsky et al. 2017) didn’t even attempt this and just used the Ne of the whole sampled population, and divided by the length of the whole sampled area.

This is another area of uncertainty, so we should model the uncertainty in neighborhood length. We know its between 10 and 40 km based on the Ne vs. Sampling Window analysis above…


De_error_NC <- Ne_error_NC/ rnorm(100000,mean=meandists_NC,sd = 15/1.96)

De_error_all_NC <- Ne_error_all_NC / maxdist_NC

ggplot(data = tibble(De_error_all_NC), aes(x=De_error_all_NC)) + geom_density() + xlim(0,250)
Warning: Removed 45 rows containing non-finite values (stat_density).

ggplot(data = tibble(De_error_NC), aes(x=De_error_NC)) + geom_density() + xlim(0,250)
Warning: Removed 493 rows containing non-finite values (stat_density).

Error in Neighborhood Size

Using a uniform distribution is out because there is clearly a peaked distribution in the Migraine output. So I am using a quick fit to a truncated lognormal distribution.

Migraine_Run2_Neighborhood_Theta

NSCI_NC
     NSCI1      NSCI2 
9.8516e+04 1.0000e+12 
curve(dlnorm(x, meanlog = log(NS_NC), sdlog = log(2.75e5)))

qlnorm(c(0.025,0.975),meanlog = log(NS_NC), sdlog = log(2.75e5))
[1] 1.464785e-04 3.073026e+17

Neighborhood_error_NC <- rlnormTrunc(n = 100000, meanlog = log(NS_NC), 
                                     sdlog = log(2.75e5), min = NSCI_NC[1], max = NSCI_NC[2])

ggplot(data = tibble(Neighborhood_error_NC), aes(x=Neighborhood_error_NC)) + 
  geom_density() + scale_x_log10()


sigma_error_fromNS_NC <- sqrt(Neighborhood_error_NC/(4*De_error_NC))
Warning in sqrt(Neighborhood_error_NC/(4 * De_error_NC)) :
  NaNs produced
names(sigma_error_fromNS_NC) <- NULL

sigma_error_fromNS_all_NC <- sqrt(Neighborhood_error_NC/(4*De_error_all_NC))
Warning in sqrt(Neighborhood_error_NC/(4 * De_error_all_NC)) :
  NaNs produced
names(sigma_error_fromNS_all_NC) <- NULL

ggplot(data = tibble(sigma_error_fromNS_NC), 
       aes(x=sigma_error_fromNS_NC)) +
  geom_density() + scale_x_log10()
Warning: Removed 52 rows containing non-finite values (stat_density).

ggplot(data = tibble(sigma_error_fromNS_all_NC), 
       aes(x=sigma_error_fromNS_all_NC)) +
  geom_density() + scale_x_log10()
Warning: Removed 100 rows containing non-finite values (stat_density).

Plot Dispersal Kernels


kernelplot_NC <- ggplot(data.frame(x=c(0,500)),aes(x)) + 
  map(.x = sample(sigma_error_fromNS_NC,1000), .f = function(sigma){
                              stat_function(fun = dexp, 
                                            args = list(rate = 1/sigma),
                                            colour = "lightblue",
                                            linetype=1,size=0.1,alpha = 0.2) }) +
  stat_function(fun=dexp,args=list(rate = 1/sigma_fromsigma2_NC), linetype=2,
                              aes(color="Migraine_Sigma2"), show.legend = T) +
  stat_function(fun=dexp,args=list(rate = 1/sigma_fromNS_NC), linetype=2,
                              aes(color="Migraine_Neighborhood_Size"), show.legend = T) +
  stat_function(fun=dexp,args=list(rate = 1/sigma_fromNS_all_NC), linetype=2,
                              aes(color="Migraine_Neighborhood_Size_OnePop"), show.legend = T) +
  xlab("Alongshore Distance (km)") + ylab("Dispersal probability density") +
  scale_color_manual("Kernel",values = 
                    c(Migraine_Sigma2="darkblue", 
                    Migraine_Neighborhood_Size ="blue",
                    Migraine_Neighborhood_Size_OnePop = "darkcyan")) +
  ylim(0,0.01) 


kernelplot_NC
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 101 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).

Fiji

Traditional Isolation by Distance Method

Based on the OG (Rousset 1997) estimator from slope of the IBD regression.

Calculate distance matrices

Weir and Cockerham’s Fst and other basic stats.


Daruanus.Fiji.hfst <- genind2hierfstat(Daruanus.Fiji)
Daruanus.Fiji.loci <- genind2loci(Daruanus.Fiji)
#gen.loci <- genind2loci(gen)
stats.Fiji <- basic.stats(Daruanus.Fiji)
theta.Fiji <- theta.msat(Daruanus.Fiji.loci)
#mean theta
mean(theta.Fiji[,2])
[1] 61.06467
fst.Fiji <- genet.dist(Daruanus.Fiji.hfst, method = "WC84")
# mean Fis values
stats.Fiji$Fis %>% as_tibble() %>% summarize(across(everything(),mean, na.rm=TRUE))
# linearize
fst.Fiji <- fst.Fiji/(1-fst.Fiji)
Geographic Distances

Also, given the circular nature of Viti Levu, the Euclidean distances measured with pointDistance() are going to be short. So I measured distances between each neighboring locality along the reef in Google Earth, as given in fijidistances

This code creates a kml file for import into Google Earth.

fijipops.sp<-fijipops[c(1,2,3,5,4)]
coordinates(fijipops.sp) <- c("decimalLongitude","decimalLatitude")
proj4string(fijipops.sp) <- CRS("+proj=longlat +datum=WGS84")
#writeOGR(fijipops.sp, dsn="Fiji/fijipops.kml", layer = "Daruanus samples", driver = "KML")

I used these points to measure distances in Google Earth. The total sampled length from Ovalu in the east to the Yasawas in the northwest was a total of ~414km.

#calculate great circle distance
gcdists_Fiji <- as.dist(pointDistance(fijipops.sp, lonlat=T)/1000)
attr(gcdists_Fiji, "Labels") <- fijipops$Abbr
gcdists.mat_Fiji <- as.matrix(gcdists_Fiji)
#write.csv(as.matrix(gen.fst_Fiji), "Daruanus_linearizedFst.csv", row.names = F, quote=F)
#write.csv(as.matrix(gcdists_Fiji), "Daruanus_gcdists.csv", row.names = F, quote=F)

#pull out a few other distances we'll need
neighbordists_Fiji <- gcdists.mat_Fiji[row(gcdists.mat_Fiji) == col(gcdists.mat_Fiji) + 1]
#distfromP1 <- gcdists.mat[,1]

#meandists <- mean(neighbordists)
fijidistances <- c((106.03-98.16), (155.22-106.03), (188.58-155.22), (273.50-188.58),
                   (370-273.50), (378.13-370.0))

meandists_Fiji <- mean(fijidistances)
maxdist_Fiji <- 378.13-98.16

fijidistances
[1]  7.87 49.19 33.36 84.92 96.50  8.13

This gives us a mean sampling distance of 46.6616667

Create Dispersal Kernel

Calculate linear model

lmodel_plot_Fiji <- ggplot(distances,aes(x=distance,y=fst)) +
                geom_point() + geom_smooth(method=lm) + xlab("Geographic Distance (km)") + 
                ylab(expression(F["ST"]/1-F["ST"])) + 
                geom_text(label = paste("m =", round(slope_Fiji,8), 
                                        "; Mantel r =", mantelr,
                                        ", p =", pvalue ), 
                          mapping = aes(x = 80, y = -0.002))

lmodel_plot_Fiji
`geom_smooth()` using formula 'y ~ x'

And after removing the 3 wonky loci, the slope is very slightly positive!

Calculate Effective Size

Pull out just the relevant Fiji estimates of Ne. The negative numbers reflect very high values of Ne!


Ne_estimates_Fiji <- Ne_estimates_f %>% filter(Population %in% fijipops$Abbr)

#
Ne_estimates_Fiji[,c(1:4,8,11,12)]



# harmonic mean of Ne, following Waples and Do 2010
Ne_hm_Fiji <- harm_mean(Ne_estimates_Fiji$Ne)

Ne vs. Sampling Window

Let’s cluster the sites by UPGMA (using Euclidean distances)

plot(hclust(gcdists_Fiji,"average"))

10km

Let’s explore Ne and Fis when lumping populations… First lump populations that are less than 10 km apart

stats.Fiji$Fis %>% as_tibble() %>% summarize(across(everything(),mean, na.rm=TRUE))

Daruanus.Fiji.10km <- Daruanus.Fiji

Daruanus.Fiji.10km@pop <-  Daruanus.Fiji.10km@pop %>% fct_collapse(
   east = c("Suva","Muaiv"),
   west = c("Mata","Tave")
 )

Daruanus.Fiji.10km.stats <- basic.stats(Daruanus.Fiji.10km)

Daruanus.Fiji.10km.stats$Fis %>% as_tibble() %>% summarize(across(everything(),mean, na.rm=TRUE))

#genind_to_genepop(Daruanus.Fiji.10km,output = "Daruanus/Fiji/Daruanus_Fiji_10km.txt")

Ne_estimates_Fiji10km <- read_NeEstimator(
                        "NeEstimator/Daruanus_LDNe_Fiji_10kmxLD.txt")
Warning: 51 parsing failures.
row            col               expected   actual                                         file
  1 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_Fiji_10kmxLD.txt'
  1 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_Fiji_10kmxLD.txt'
  2 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_Fiji_10kmxLD.txt'
  2 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_Fiji_10kmxLD.txt'
  3 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_Fiji_10kmxLD.txt'
... .............. ...................... ........ ............................................
See problems(...) for more details.
Ne_estimates_Fiji10km <- WDFilter(Ne_estimates_Fiji10km, 10)


Ne_hm_Fiji10km <- harm_mean(Ne_estimates_Fiji10km$Ne)

40km

Now move up to 40 km

Daruanus.Fiji.40km <- Daruanus.Fiji

Daruanus.Fiji.40km@pop <-  Daruanus.Fiji.10km@pop %>% fct_collapse(
   east = c("Suva","Muaiv"),
   center = c("Yanu","Taga"),
   west = c("Mata","Tave")
 )
Warning: Unknown levels in `f`: Suva, Muaiv, Mata, Tave
Daruanus.Fiji.40km.stats <- basic.stats(Daruanus.Fiji.40km)

Daruanus.Fiji.40km.stats$Fis %>% as_tibble() %>% summarize(across(everything(),mean, na.rm=TRUE))

#genind_to_genepop(Daruanus.Fiji.40km,output = "Daruanus/Fiji/Daruanus_Fiji_40km.txt")

Ne_estimates_Fiji40km <- read_NeEstimator(file = "NeEstimator/Daruanus_LDNe_Fiji_40kmxLD.txt")
Warning: 41 parsing failures.
row            col               expected   actual                                         file
  1 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_Fiji_40kmxLD.txt'
  1 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_Fiji_40kmxLD.txt'
  2 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_Fiji_40kmxLD.txt'
  2 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_Fiji_40kmxLD.txt'
  3 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_Fiji_40kmxLD.txt'
... .............. ...................... ........ ............................................
See problems(...) for more details.
Ne_estimates_Fiji40km <- WDFilter(Ne_estimates_Fiji40km, 10)

Ne_hm_Fiji40km <- harm_mean(Ne_estimates_Fiji40km$Ne)

100km

Now move up to 100 km

Daruanus.Fiji.100km <- Daruanus.Fiji

Daruanus.Fiji.100km@pop <-  Daruanus.Fiji.100km@pop %>% fct_collapse(
   east = c("Suva","Muaiv","Yanu","Taga"),
   west = c("Mata","Tave","Nadi")
 )

Daruanus.Fiji.100km.stats <- basic.stats(Daruanus.Fiji.100km)

Daruanus.Fiji.100km.stats$Fis %>% as_tibble() %>% summarize(across(everything(),mean, na.rm=TRUE))

#genind_to_genepop(Daruanus.Fiji.100km,output = "Fiji/Daruanus_Fiji_100km.txt")

Ne_estimates_Fiji100km <- read_NeEstimator(file =
                                             "NeEstimator/Daruanus_LDNe_Fiji_100kmxLD.txt")
Warning: 31 parsing failures.
row            col               expected   actual                                          file
  1 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_Fiji_100kmxLD.txt'
  1 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_Fiji_100kmxLD.txt'
  2 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_Fiji_100kmxLD.txt'
  2 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_Fiji_100kmxLD.txt'
  3 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_Fiji_100kmxLD.txt'
... .............. ...................... ........ .............................................
See problems(...) for more details.
Ne_estimates_Fiji100km <- WDFilter(Ne_estimates_Fiji100km, 10)

Ne_hm_Fiji100km <- harm_mean(Ne_estimates_Fiji100km$Ne)

300km

300km (all pops as one)

Ne_estimates_Fiji300km <- read_NeEstimator(file =
                                             "NeEstimator/Daruanus_LDNe_Fiji_1popxLD.txt")
Warning: 12 parsing failures.
row            col               expected   actual                                         file
  1 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_Fiji_1popxLD.txt'
  1 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_Fiji_1popxLD.txt'
  2 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_Fiji_1popxLD.txt'
  2 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_Fiji_1popxLD.txt'
  3 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_Fiji_1popxLD.txt'
... .............. ...................... ........ ............................................
See problems(...) for more details.
Ne_estimates_Fiji300km <- WDFilter(Ne_estimates_Fiji300km, 10)



Ne_hm_Fiji300km <- 20000
Ne_all_Fiji <- Ne_estimates_Fiji300km$Ne

Ne_all_Fiji_CI <- c(Ne_estimates_Fiji300km$ParametricLow,Ne_estimates_Fiji300km$ParametricHigh)

Figure

fijiwindows <- tibble(SampleWindow = c(0,10,40,100,300),
                      hm_Ne = c(Ne_hm_Fiji,Ne_hm_Fiji10km,Ne_hm_Fiji40km,Ne_hm_Fiji100km,
                                Ne_hm_Fiji300km))

ggplot(fijiwindows, aes(x = SampleWindow, y = hm_Ne)) + geom_point() + 
  geom_line() + ylim(0,20000) + xlim(0,300)
ggsave("Fiji_Ne_v_SampDistance.pdf",height = 7, width = 7)

Calculate Effective Density

# Divide by mean distance between sampling sites to get density
De_Fiji <- Ne_hm_Fiji/meandists_Fiji
#De_all_Fiji <- Ne_all_Fiji / maxdist_Fiji

Mean density is 82.3843306 individuals/km. If we do the whole sample as a single population, Ne is “infinite” so this isn’t useful.

Calculate sigma

Following Rousset’s (1997) equation:

\[ \frac{1}{m} = 4D_e\sigma^2 \]

Which (Pinsky et al. 2017) re-arranged to give:

\[ \sigma = \sqrt{\frac{1}{4D_em}} \]

So now let’s plug that into the first equation!


sigma_fromSlope_Fiji <- sqrt(1 / (4*De_Fiji*slope_Fiji))

#sigma_fromSlope_all_Fiji <- sqrt(1 / (4*De_all_Fiji*slope_Fiji))

\(\sigma\) estimated from this slope is 63.67 km if I use the harmonic mean Ne for density. I can’t use the Ne from the whole population because it is infinite.

MigraiNe Method

Running MigraiNe

First Run

GenepopFileName=../Daruanus_Fiji.txt
DemographicModel= LinearIBD
#I modified the genepop file by adding sampling coordinates as the name of the 
#last individual in each population. These coordinates were distances in km 
#along the Viti Levu reef and coastline from Ovalu in the east to the Yasawas 
#in the northwest: a total of ~414km. I measured all distances in Google Earth
PSONMax=414 0
#Neighborhood size is based on mean distance between populations = 46.66
#414/46.66 = 8.87 so I will use 10 bins
GeoBinNbr=10
GeoUnit= ind.km
#alternate way of specifying the habitat, not used for now
#habitatPars= 0.5 0.5 400 1 0
#habitatPars=0 0 0 300 0
#Mutation Model is K-allele = PIM, with k=2 for SNPs. GivenK is number of alleles
# at each locus (Daruanus.Fiji@loc.n.all)
MutationModel=PIM
GivenK=22,27,8,46,47,30,24,20,52,31,38
samplingSpace=,,
samplingScale=,,
#Analysis - this will do 5 runs of 100 points and
#overwrite those with 10 runs of 250 points
writeSequence= Over,Over,Over,Over,Over,Append,10
StatisticSequence=PAC
PointNumber=100,100,100,100,100,250
Nrunsperpoint=30,30,30,30,30,50
#Wide priors on Neu, Nem and g
LowerBound=0.1,1,0
Upperbound=1,2500,1
oneDimCI= 2Nmu, 2Nm, Nb, condS2
CoreNbrForR=4
#Plots= all1DProfiles
1DProfiles=2Nmu, 2Nm, Nb, condS2, g
extrascale=Nb=logscale
graphicFormat=pdf
#writeAdHocFiles=T

This run completed in 147 minutes

Second Run

A second run where I widen the prior on theta and Nm.

GenepopFileName=../Daruanus_Fiji.txt
DemographicModel=LinearIBD
#I modified the genepop file by adding sampling coordinates as the name of the 
#last individual in each population. These coordinates were distances in km 
#along the Viti Levu reef and coastline from Ovalu in the east to the Yasawas 
#in the northwest: a total of ~414km. I measured all distances in Google Earth
PSONMax=414 0
#Neighborhood size is based on mean distance between populations = 46.66
#414/46.66 = 8.87 so I will use 10 bins
GeoBinNbr=10
GeoUnit= ind.km
#alternate way of specifying the habitat, not used for now
#habitatPars= 0.5 0.5 400 1 0
#habitatPars=0 0 0 300 0
#Mutation Model is K-allele = PIM, with k=2 for SNPs. GivenK is number of alleles
# at each locus (Daruanus.Fiji@loc.n.all)
MutationModel=PIM
GivenK=22,27,8,46,47,30,24,20,52,31,38
samplingSpace=,,
samplingScale=,,
#Analysis - this will do 5 runs of 100 points and
#overwrite those with 10 runs of 250 points
writeSequence= Over,Over,Over,Over,Over,Append,10
StatisticSequence=PAC
PointNumber=100,100,100,100,100,250
Nrunsperpoint=30,30,30,30,30,50
#Wide priors on Neu, Nem and g
LowerBound=0.1,1,0
Upperbound=1,2500,1
oneDimCI= 2Nmu, 2Nm, Nb, condS2
CoreNbrForR=4
#Plots= all1DProfiles
1DProfiles=2Nmu, 2Nm, Nb, condS2, g
extrascale=Nb=logscale
graphicFormat=pdf
#writeAdHocFiles=T

This result finished in the same amount of time and with very similar results to the first!

Third Run

Removing 3 loci and using the condS2 search parameterization

GenepopFileName=../../Daruanus_Fiji.txt
DemographicModel=LinearIBD
#I modified the genepop file by adding sampling coordinates as the name of the 
#last individual in each population. These coordinates were distances in km 
#along the Viti Levu reef and coastline from Ovalu in the east to the Yasawas 
#in the northwest: a total of ~414km. I measured all distances in Google Earth
PSONMax=414 0
#Neighborhood size is based on mean distance between populations = 46.66
#414/46.66 = 8.87 so I will use 10 bins
GeoBinNbr=10
GeoUnit= ind.km
#alternate way of specifying the habitat, not used for now
#habitatPars= 0.5 0.5 400 1 0
#habitatPars=0 0 0 300 0
#Mutation Model is K-allele = PIM, with k=2 for SNPs. GivenK is number of alleles
# at each locus (Daruanus.Fiji@loc.n.all)
MutationModel=PIM
GivenK=22,8,46,30,24,20,52,38
samplingSpace=,,condS2
samplingScale=,,logscale
#Analysis - this will do 5 runs of 100 points and
#overwrite those with 10 runs of 250 points
writeSequence= Over,Over,Over,Over,Over,Append,10
StatisticSequence=PAC
PointNumber=100,100,100,100,100,250
Nrunsperpoint=30,30,30,30,30,50
#Wide priors on Neu, Nem and g
LowerBound=0.1,1,1
Upperbound=2,10000,100000
oneDimCI= 2Nmu, 2Nm, Nb, condS2
CoreNbrForR=4
#Plots= all1DProfiles
1DProfiles=2Nmu, 2Nm, Nb, condS2, g
extrascale=Nb=logscale
graphicFormat=pdf
writeAdHocFiles=T

Finished in 112.9333333 minutes.

Create Dispersal Kernels

This got me the following estimates.

Output from run 2.


runDir <- "/Users/eric/github/IBD_Kernels/Daruanus/Fiji/Migraine/run3"
result <- read_migraine(runDir)
Read 20 items
  
NS_Fiji <- result["NS"]
NSCI_Fiji <- c(result["NSCI1"],result["NSCI2"])
Nmu_Fiji <- result["Nmu"]
Nm_Fiji <- result["Nm"]
g_Fiji <- result["g"]
lattice2geog_Fiji <- result["lattice2geog"]

sigma2_Fiji <- g_to_sigma2(g_Fiji)
sigma_fromsigma2_Fiji <- sqrt(sigma2_Fiji*lattice2geog_Fiji)
sigma_fromNS_Fiji <- sqrt(NS_Fiji/(4*De_Fiji))
sigmaCI_fromNS_Fiji <- sqrt(NSCI_Fiji/(4*De_Fiji))

The \(\sigma\) we get from Neighborhood Size \(\sigma\) is 31.1842975. We get a much lower estimate from \(\sigma^2\), with \(\sigma\) = 5.9242717

Confidence Intervals

Propagating error sorta following Pinsky et al. table S2

Error in Effective Size

For Harmonic Mean Method
Ne_estimates_Fiji$JackknifeHigh[which(is.na(Ne_estimates_Fiji$JackknifeHigh))] <- 20000
Ne_estimates_Fiji$JackknifeHigh <- as.numeric(Ne_estimates_Fiji$JackknifeHigh)
Ne_estimates_Fiji$JackknifeLow <- as.numeric(Ne_estimates_Fiji$JackknifeLow)

Ne_error_Fiji <- NULL
for(n in 1:100000){
  hm <- harm_mean(mapply(runif, n=1, 
                   min=Ne_estimates_Fiji$JackknifeLow,
                   max=Ne_estimates_Fiji$JackknifeHigh))
  Ne_error_Fiji <- c(Ne_error_Fiji,hm)
}
names(Ne_error_Fiji)<-NULL

ggplot(data = tibble(Ne_error_Fiji), aes(x=Ne_error_Fiji)) + geom_density()

For Whole Sample Method

Can’t do the whole sample method, because Ne estimate is “infinite”

Error in Effective Density

Will model the error in meandist as well…


De_error_Fiji <- Ne_error_Fiji/ rnormTrunc(100000,mean=meandists_Fiji,
                                           sd = meandists_Fiji/1.96, min = 1e-10)

Error in Slope

ggplot(data = tibble(sigma_error_fromSlope_Fiji), aes(x=sigma_error_fromSlope_Fiji)) +
  geom_density() + xlim(0,1000)  + scale_x_log10()
Scale for 'x' is already present. Adding another scale for 'x', which will replace
the existing scale.

Error in Neighborhood Size

Using a uniform distribution is out because there is clearly a peaked distribution in the Migraine output. So I am using a quick fit to a lognormal distribution

Migraine_Run2_Neighborhood_Theta

NSCI_Fiji
    NSCI1     NSCI2 
   122779 101654085 
qlnorm(c(0.025,0.975),meanlog = log(NS_Fiji), sdlog = log(18.89))
[1] 1.010201e+03 1.016589e+08

Neighborhood_error_Fiji <- rlnormTrunc(n = 100000, meanlog = log(NS_Fiji), 
                                     sdlog = log(18.89), min = NSCI_Fiji[1], max = NSCI_Fiji[2])

ggplot(data = tibble(Neighborhood_error_Fiji), aes(x=Neighborhood_error_Fiji)) + 
  geom_density() + scale_x_log10()


sigma_error_fromNS_Fiji <- sqrt(Neighborhood_error_Fiji/(4*De_error_Fiji))

names(sigma_error_fromNS_Fiji) <- NULL

ggplot(data = tibble(sigma_error_fromNS_Fiji), 
       aes(x=sigma_error_fromNS_Fiji)) +
       geom_density() + scale_x_log10()

Plot Dispersal Kernels

kernelplot_Fiji <- ggplot(data.frame(x=c(0,100)),aes(x)) +
  map(.x = sample(sigma_error_fromNS_Fiji,1000), .f = function(sigma){
                              stat_function(fun = dexp, args = list(rate = 1/sigma),
                                            colour = "lightblue",
                                            linetype=1,size=0.1,alpha = 0.2) }) +
  map(.x = sample(sigma_error_fromSlope_Fiji,1000), .f = function(sigma){
                              stat_function(fun = dexp, args = list(rate = 1/sigma),
                                            colour = "lightgreen",
                                            linetype=1,size=0.1,alpha = 0.2) }) +
  stat_function(fun=dexp,args=list(rate = 1/sigma_fromSlope_Fiji), linetype=2,
                              aes(color="IBD_Slope"), show.legend = T) +
  stat_function(fun=dexp,args=list(rate = 1/sigma_fromsigma2_Fiji), linetype=2,
                              aes(color="Migraine_Sigma2"), show.legend = T) +
  stat_function(fun=dexp,args=list(rate = 1/sigma_fromNS_Fiji), linetype=2,
                              aes(color="Migraine_Neighborhood_Size"), show.legend = T) +
  xlab("Alongshore Distance (km)") + ylab("Dispersal probability density") +
  scale_color_manual("Kernel",values = 
                    c(Migraine_Sigma2="darkblue", 
                    Migraine_Neighborhood_Size ="blue",
                    IBD_Slope = "green")) +
  ylim(0,0.05)


kernelplot_Fiji
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 5 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).
Warning: Removed 7 row(s) containing missing values (geom_path).
Warning: Removed 6 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 8 row(s) containing missing values (geom_path).

The reason that the error is generally smaller than the estimate is because the upper bounds of Ne are often unbounded, and treated as 20,000.

Society Islands

Traditional Isolation by Distance Method

Based on the OG (Rousset 1997) estimator from slope of the IBD regression.

Calculate distance matrices

Weir and Cockerham’s Fst and other basic stats.

Daruanus.FP.hfst <- genind2hierfstat(Daruanus.FP)
Daruanus.FP.loci <- genind2loci(Daruanus.FP)
#gen.loci <- genind2loci(gen)
stats.FP <- basic.stats(Daruanus.FP)
theta.FP <- theta.msat(Daruanus.FP.loci)
#mean theta
mean(theta.FP[,2])
fst.FP <- genet.dist(Daruanus.FP.hfst, method = "WC84")
# mean Fis values
stats.FP$Fis %>% as_tibble() %>% summarize(across(everything(),mean, na.rm=TRUE))
# linearize
fst.FP <- fst.FP/(1-fst.FP)
#write.csv(as.matrix(fst.FP), "Daruanus_FP_linearizedFst.csv", row.names = F, quote=F)
Geographic Distances

Calculate great circle distance

gcdists_FP <- as.dist(pointDistance(FPpops[,c(5,4)], lonlat=T)/1000)
attr(gcdists_FP, "Labels") <- FPpops$Abbr
gcdists.mat_FP <- as.matrix(gcdists_FP)

Now to follow what Malin did, and create a principal components axis, and measure distance along it.

# because we only care about the x axis, we need to reorder,so that Tetiaroa comes after Puna and before Temae
FPpops <- FPpops[c(1,4,2,3,5),]
FPpops.sp <- SpatialPointsDataFrame(FPpops[,c(5,4)], data = FPpops, 
                                        proj4string = CRS("+proj=longlat  +datum=WGS84"))
FPpops.utm <- spTransform(FPpops.sp, CRS("+proj=utm +zone56S +datum=WGS84"))
#as.dist(pointDistance(localities.utm,latlon=F)/1000)
#principal components without scaling or centering, we just want the rotation
pc_FP <- prcomp(FPpops.utm@coords, retx=T, scale=F,center=F)
plot(pc_FP$x)

#set PC2 axis to zero
pc1_FP<-cbind(pc_FP$x[,1],0)


pcdists_FP <- as.dist(pointDistance(pc1_FP,lonlat=F)/1000)

attr(pcdists_FP, "Labels") <- FPpops$Abbr
#write.csv(as.matrix(pcdists), "Apercula_pcdists.csv", row.names = T, quote=F)
pcdists.mat_FP <- as.matrix(pcdists_FP)

#pull out a few other distances we'll need
neighbordists_FP <- pcdists.mat_FP[row(pcdists.mat_FP) == col(pcdists.mat_FP) + 1]
distfromP1_FP <- pcdists.mat_FP[,1]
maxdist_FP <- max(pcdists.mat_FP)
meandists_FP <- mean(neighbordists_FP)

Mean sampling distance is 65.7654103 km. But note that Tetiaroa occurs only a couple of kilometers from the Moorea population because they are being forced onto the rotated X axis.

Create Dispersal Kernel

Calculate linear model

First to get the slope \(m\) we need to make a simple linear model. I don’t think significance is really important here, but we can calculate that with a Mantel test.

# mantel test
mantelt<-mantel.randtest(fst.FP,pcdists_FP, nrepet = 10000)

distances <- tibble(distance=as.vector(pcdists_FP),fst=as.vector(fst.FP))

lmodel_FP <- lm(fst ~ distance , distances)

slope_FP <- lmodel_FP$coefficients[2]
mantelr <- round(mantelt$obs, 2)
pvalue <- round(mantelt$pvalue, 5)

lmodel_plot_FP <- ggplot(distances,aes(x=distance,y=fst)) +
                geom_point() + geom_smooth(method=lm) + xlab("Geographic Distance (km)") + 
                ylab(expression(F["ST"]/1-F["ST"])) + 
                geom_text(label = paste("m =", slope_FP, 
                                        "; Mantel r =", mantelr,
                                        ", p =", pvalue ), 
                          mapping = aes(x = 80, y = -0.002))

lmodel_plot_FP
`geom_smooth()` using formula 'y ~ x'

#ggsave("FP_IBD.pdf", plot=lmodel_plot,device="pdf", width=7, height=5,units="in")

E voila, c’est positive! But not significantly so.

Calculate Effective Size

Pull out just the relevant FP estimates of Ne. The negative numbers reflect very high values of Ne!


Ne_estimates_FP <- Ne_estimates_f %>% filter(Population %in% FPpops$Abbr)

#
Ne_estimates_FP[,c(1:4,8,11,12)]

# harmonic mean of Ne, following Waples and Do 2010
Ne_hm_FP <- harm_mean(Ne_estimates_FP$Ne)

Ne vs. Sampling Window

Let’s cluster the sites by UPGMA (using Euclidean distances)

plot(hclust(pcdists_FP,"average"))

10km

Let’s explore Ne and Fis when lumping populations… First lump populations that are less than 10 km apart

stats.FP$Fis %>% as_tibble() %>% summarize(across(everything(),mean, na.rm=TRUE))
meanFis_FP <- stats.FP$Fis %>% as_tibble() %>%
  summarize(across(everything(),mean, na.rm=TRUE)) %>% summarize(meanFis = rowMeans(.))

Daruanus.FP.10km <- Daruanus.FP

Daruanus.FP.10km@pop <-  Daruanus.FP.10km@pop %>% fct_collapse(
   TemTetia = c("Tetia","Tem")
 )

Daruanus.FP.10km.stats <- basic.stats(Daruanus.FP.10km)

Daruanus.FP.10km.stats$Fis %>% as_tibble() %>% summarize(across(everything(),mean, na.rm=TRUE))

meanFis_FP_10km <- Daruanus.FP.10km.stats$Fis %>% as_tibble() %>%
  summarize(across(everything(),mean, na.rm=TRUE)) %>% summarize(meanFis = rowMeans(.))

#genind_to_genepop(Daruanus.FP.10km,output = "Daruanus/FP/Daruanus_FP_10km.txt")

Ne_estimates_FP10km <- read_NeEstimator(
                        "NeEstimator/Daruanus_LDNe_FP_10kmxLD.txt")
Warning: 33 parsing failures.
row            col               expected   actual                                       file
  1 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_FP_10kmxLD.txt'
  1 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_FP_10kmxLD.txt'
  2 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_FP_10kmxLD.txt'
  2 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_FP_10kmxLD.txt'
  3 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_FP_10kmxLD.txt'
... .............. ...................... ........ ..........................................
See problems(...) for more details.
Ne_estimates_FP10km <- WDFilter(Ne_estimates_FP10km, 10)


Ne_hm_FP10km <- harm_mean(Ne_estimates_FP10km$Ne)

20km

Daruanus.FP.20km <- Daruanus.FP

Daruanus.FP.20km@pop <-  Daruanus.FP.20km@pop %>% fct_collapse(
   TemTetiaMo = c("Tetia","Tem","Mo")
 )

Daruanus.FP.20km.stats <- basic.stats(Daruanus.FP.20km)

Daruanus.FP.20km.stats$Fis %>% as_tibble() %>% summarize(across(everything(),mean, na.rm=TRUE))

meanFis_FP_20km <- Daruanus.FP.20km.stats$Fis %>% as_tibble() %>%
  summarize(across(everything(),mean, na.rm=TRUE)) %>% summarize(meanFis = rowMeans(.))

#genind_to_genepop(Daruanus.FP.20km,output = "Daruanus/FP/Daruanus_FP_20km.txt")

Ne_estimates_FP20km <- read_NeEstimator(file = "NeEstimator/Daruanus_LDNe_FP_20kmxLD.txt")
Warning: 23 parsing failures.
row            col               expected   actual                                       file
  1 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_FP_20kmxLD.txt'
  1 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_FP_20kmxLD.txt'
  2 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_FP_20kmxLD.txt'
  2 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_FP_20kmxLD.txt'
  3 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_FP_20kmxLD.txt'
... .............. ...................... ........ ..........................................
See problems(...) for more details.
Ne_estimates_FP20km <- WDFilter(Ne_estimates_FP20km, 10)

Ne_hm_FP20km <- harm_mean(Ne_estimates_FP20km$Ne)

40km

Now move up to 40 km

Daruanus.FP.40km <- Daruanus.FP

Daruanus.FP.40km@pop <-  Daruanus.FP.40km@pop %>% fct_collapse(
   East = c("Tetia","Tem","Mo","Puna")
 )

Daruanus.FP.40km.stats <- basic.stats(Daruanus.FP.40km)

Daruanus.FP.40km.stats$Fis %>% as_tibble() %>% summarize(across(everything(),mean, na.rm=TRUE))

meanFis_FP_40km <- Daruanus.FP.40km.stats$Fis %>% as_tibble() %>%
  summarize(across(everything(),mean, na.rm=TRUE)) %>% summarize(meanFis = rowMeans(.))

#genind_to_genepop(Daruanus.FP.40km,output = "Daruanus/FP/Daruanus_FP_40km.txt")

Ne_estimates_FP40km <- read_NeEstimator(file = "NeEstimator/Daruanus_LDNe_FP_40kmxLD.txt")
Warning: 13 parsing failures.
row            col               expected   actual                                       file
  4 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_FP_40kmxLD.txt'
  6 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_FP_40kmxLD.txt'
  6 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_FP_40kmxLD.txt'
  7 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_FP_40kmxLD.txt'
  7 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_FP_40kmxLD.txt'
... .............. ...................... ........ ..........................................
See problems(...) for more details.
Ne_estimates_FP40km <- WDFilter(Ne_estimates_FP40km, 10)

Ne_hm_FP40km <- harm_mean(Ne_estimates_FP40km$Ne)

300km

300km (all pops as one)

Ne_estimates_FP300km <- read_NeEstimator(file =
                                             "NeEstimator/Daruanus_LDNe_FP_1popxLD.txt")
Warning: 12 parsing failures.
row            col               expected   actual                                       file
  1 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_FP_1popxLD.txt'
  1 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_FP_1popxLD.txt'
  2 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_FP_1popxLD.txt'
  2 JackknifeHigh  no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_FP_1popxLD.txt'
  3 ParametricHigh no trailing characters Infinite 'NeEstimator/Daruanus_LDNe_FP_1popxLD.txt'
... .............. ...................... ........ ..........................................
See problems(...) for more details.
Ne_estimates_FP300km <- WDFilter(Ne_estimates_FP300km, 10)



Ne_hm_FP300km <- Ne_estimates_FP300km$Ne
Ne_all_FP <- Ne_estimates_FP300km$Ne

Ne_all_FP_CI <- c(Ne_estimates_FP300km$ParametricLow,20000)

Figure

FPwindows <- tibble(SampleWindow = c(0,10,40,300),
                      hm_Ne = c(Ne_hm_FP,Ne_hm_FP10km,Ne_hm_FP40km,Ne_hm_FP300km))

FPNevDistance <- ggplot(FPwindows, aes(x = SampleWindow, y = hm_Ne)) + geom_point() + geom_line() + ylim(0,20000) + xlim(0,300)
FPNevDistance

#ggsave("FP_Ne_v_SampDistance.pdf", height = 7, width = 7)

Calculate Effective Density

# Divide by mean distance between sampling sites to get density
De_FP <- Ne_hm_FP/meandists_FP
De_all_FP <- Ne_all_FP/maxdist_FP

Mean density in the Societies is 15.466959 inds/km, or really really large if we consider the whole sample as a single population 44.7522487

Calculate sigma

Following Rousset’s (1997) equation:

\[ \frac{1}{m} = 4D_e\sigma^2 \]

Which (Pinsky et al. 2017) re-arranged to give:

\[ \sigma = \sqrt{\frac{1}{4D_em}} \]

So now let’s plug that into the first equation!


sigma_fromSlope_FP <- sqrt(1 / (4*De_FP*slope_FP))

sigma_fromSlope_all_FP <- sqrt(1 / (4*De_all_FP*slope_FP))

So effective density is 15.47 individuals per km, and \(\sigma\) is 49.41 km if we calculate density based on harmonic mean of Ne, or rsignif(sigma_fromSlope_all_FP,4)` km if we calculate it across the whole sample.

MigraiNe Method

Running MigraiNe

First Run

I modified the genepop file by adding sampling coordinates as the name of the last individual in each population. There is no coastline for these samples, which each come from different islands. I just measured from Tahiti to Maupiti It’s 65 km from the tip of Tahiti Iti to Puna, so I added that to each coordinate

distfromP1_FP+65
GenepopFileName=../Daruanus_FP.txt
DemographicModel= LinearIBD
#I modified the genepop file by adding sampling coordinates as the name of the 
#last individual in each population. There is no coastline for these samples,
# which each come from different islands. I just measured from Tahiti to Maupiti
# It's 65 km from the tip of Tahiti Iti to Puna, so I added that to 
# each coordinate.
PSONMax=355 0
#Neighborhood size is based on mean distance between populations = 75.78
#355/75.78 = 4.684 so I will use 6 bins
GeoBinNbr=6
GeoUnit= ind.km
#alternate way of specifying the habitat, not used for now
#habitatPars= 0.5 0.5 400 1 0
#habitatPars=0 0 0 300 0
#Mutation Model is K-allele = PIM, with k=2 for SNPs. GivenK is number of alleles
# at each locus (Daruanus.FP@loc.n.all)
MutationModel=PIM
GivenK=21,24,8,37,43,26,19,16,43,31,40
samplingSpace=,,
samplingScale=,,
#Analysis - this will do 5 runs of 100 points and
#overwrite those with 10 runs of 250 points
writeSequence= Over,Over,Over,Over,Over,Append,10
StatisticSequence=PAC
PointNumber=100,100,100,100,100,250
Nrunsperpoint=30,30,30,30,30,50
#Wide priors on Neu, Nem and g
LowerBound=0.1,1,0
Upperbound=2,10000,1
oneDimCI= 2Nmu, 2Nm, Nb, condS2
CoreNbrForR=4
#Plots= all1DProfiles
1DProfiles=2Nmu, 2Nm, Nb, condS2, g
extrascale=Nb=logscale
graphicFormat=pdf
#writeAdHocFiles=T

The first run finished with an error, but a second identical run completed in 50.8666667 minutes. Both runs had very similar results.

Second Run

Widened the prior on theta because the first two runs were over

GenepopFileName=../Daruanus_FP.txt
DemographicModel= LinearIBD
#I modified the genepop file by adding sampling coordinates as the name of the 
#last individual in each population. There is no coastline for these samples,
# which each come from different islands. I just measured from Tahiti to Maupiti
# It's 65 km from the tip of Tahiti Iti to Puna, so I added that to 
# each coordinate.
PSONMax=355 0
#Neighborhood size is based on mean distance between populations = 75.78
#355/75.78 = 4.684 so I will use 6 bins
GeoBinNbr=6
GeoUnit= ind.km
#alternate way of specifying the habitat, not used for now
#habitatPars= 0.5 0.5 400 1 0
#habitatPars=0 0 0 300 0
#Mutation Model is K-allele = PIM, with k=2 for SNPs. GivenK is number of alleles
# at each locus (Daruanus.FP@loc.n.all)
MutationModel=PIM
GivenK=21,24,8,37,43,26,19,16,43,31,40
samplingSpace=,,
samplingScale=,,
#Analysis - this will do 5 runs of 100 points and
#overwrite those with 10 runs of 250 points
writeSequence= Over,Over,Over,Over,Over,Append,10
StatisticSequence=PAC
PointNumber=100,100,100,100,100,250
Nrunsperpoint=30,30,30,30,30,50
#Wide priors on Neu, Nem and g
LowerBound=0.1,1,0
Upperbound=4,10000,1
oneDimCI= 2Nmu, 2Nm, Nb, condS2
CoreNbrForR=4
#Plots= all1DProfiles
1DProfiles=2Nmu, 2Nm, Nb, condS2, g
extrascale=Nb=logscale
graphicFormat=pdf
#writeAdHocFiles=T

Fifth Run

Removed 3 loci, used condS2 parameterization

GenepopFileName=../../Daruanus_FP.txt
DemographicModel= LinearIBD
#I modified the genepop file by adding sampling coordinates as the name of the 
#last individual in each population. There is no coastline for these samples,
# which each come from different islands. I just measured from Tahiti to Maupiti
# It's 65 km from the tip of Tahiti Iti to Puna, so I added that to 
# each coordinate.
PSONMax=355 0
#Neighborhood size is based on mean distance between populations = 75.78
#355/75.78 = 4.684 so I will use 6 bins
GeoBinNbr=6
GeoUnit= ind.km
#alternate way of specifying the habitat, not used for now
#habitatPars= 0.5 0.5 400 1 0
#habitatPars=0 0 0 300 0
#Mutation Model is K-allele = PIM, with k=2 for SNPs. GivenK is number of alleles
# at each locus (Daruanus.FP@loc.n.all)
MutationModel=PIM
GivenK=21,8,37,26,19,16,43,40
samplingSpace=,,condS2
samplingScale=,,logscale
#Analysis - this will do 5 runs of 100 points and
#overwrite those with 10 runs of 250 points
writeSequence= Over,Over,Over,Over,Over,Append,10
StatisticSequence=PAC
PointNumber=100,100,100,100,100,250
Nrunsperpoint=30,30,30,30,30,50
#Wide priors on Neu, Nem and g
LowerBound=0.1,1,1
Upperbound=4,10000,100000
oneDimCI= 2Nmu, 2Nm, Nb, condS2, g
CoreNbrForR=4
Plots= allProfiles
#1DProfiles=2Nmu, 2Nm, Nb, condS2, g
extrascale=Nb=logscale
graphicFormat=pdf
writeAdHocFiles=T

Finished in 56.45 minutes.

Create Dispersal Kernels

Sigma estimates

This got me the following estimates.

Output from run 5.


runDir <- "/Users/eric/github/IBD_Kernels/Daruanus/FP/Migraine/run5"
result <- read_migraine(runDir)
Read 20 items
  
NS_FP <- result["NS"]
NSCI_FP <- c(result["NSCI1"],result["NSCI2"])
Nmu_FP <- result["Nmu"]
Nm_FP <- result["Nm"]
g_FP <- result["g"]
lattice2geog_FP <- result["lattice2geog"]

sigma2_FP <- g_to_sigma2(g_FP)
sigma_fromsigma2_FP <- sqrt(sigma2_FP*lattice2geog_FP)
sigma_fromNS_FP <- sqrt(NS_FP/(4*De_FP))
sigmaCI_fromNS_FP <- sqrt(NSCI_FP/(4*De_FP))

sigma_fromNS_all_FP <- sqrt(NS_FP/(4*De_all_FP))
sigmaCI_fromNS_all_FP <- sqrt(NSCI_FP/(4*De_all_FP))

The \(\sigma\) we get from \(F_{ST}\) ~ Distance is 49.4136729, and from Neighborhood Size \(\sigma\) is 76.9094312. We again get a lower estimate from \(\sigma^2\), with \(\sigma\) = 14.9881621

Confidence Intervals

Propagating error sorta following Pinsky et al. table S2

Error in Ne

For Harmonic Mean Method

Following Pinsky, Montes, and Palumbi (2010) I am going to bootstrap across the confidence intervals for each Nb estimate. Unfortunately, the new jackknife method of Jones, Ovenden, and Wang (2016) often results in infinite upper bounds with marine data. I’m going to use the jackknife CIs. I’m also going to use a uniform distribution for the error because approximating the error structure with ChiSq or Normal distributions is not a simple task and I’m just trying to get a sketch of the error to compare with MigraiNe anyway. I’m going to set “Infinite” values in the upper CI to 20,000 since I rarely see upper bounds that high.

Ne_estimates_FP$JackknifeHigh[which(is.na(Ne_estimates_FP$JackknifeHigh))] <- 20000
Ne_estimates_FP$JackknifeHigh <- as.numeric(Ne_estimates_FP$JackknifeHigh)
Ne_estimates_FP$JackknifeLow <- as.numeric(Ne_estimates_FP$JackknifeLow)

Ne_error_FP <- NULL
for(n in 1:100000){
  hm <- harm_mean(mapply(runif, n=1, 
                   min=Ne_estimates_FP$JackknifeLow,
                   max=Ne_estimates_FP$JackknifeHigh))
  Ne_error_FP <- c(Ne_error_FP,hm)
}
names(Ne_error_FP)<-NULL

ggplot(data = tibble(Ne_error_FP), aes(x=Ne_error_FP)) + geom_density()

For Whole Sample Method

Naaykens and D’Aloia showed that using the whole sample to estimate density gives pretty similar results to the harmonic mean method, so I’m also going to try that.


Nb <- Ne_all_FP
r2_FP <- Ne_estimates_FP300km$r2
#from Waples 2006 table 2
er2_FP <- 1/Ne_estimates_FP300km$SampSize + 3.19/Ne_estimates_FP300km$SampSize ^2 
df_FP <- Ne_estimates_FP300km$IndAlleles

WaplesMonoNe(r2_FP - er2_FP)
[1] 11688.35
# this shows that we can get approximately what NeEstimator gives us... 
#not sure why its not exact... must be missing some correction
rCI_FP <- df_NC*r2_FP / (qchisq(c(0.025,0.975), df = df_FP))
WaplesMonoNe(rCI_NC - er2_NC)
[1]  3729.688 16288.111
#and now to get and plot the error distribution
Ne_error_all_FP <- WaplesMonoNe(((df_FP*r2_FP)/(rchisq(100000, df = df_FP))) - er2_FP)

ggplot(data = tibble(Ne_error_all_FP), aes(x=Ne_error_all_FP)) + 
  geom_density() + xlim(0,30000)
Warning: Removed 24993 rows containing non-finite values (stat_density).

NA

Error in Effective Density


De_error_FP <- Ne_error_FP /rnormTrunc(100000, mean = meandists_FP,
                                       sd = (65-10)/1.96, min = 1e-10)

De_error_all_FP <- Ne_error_all_FP / maxdist_FP

ggplot(data = tibble(De_error_FP), aes(x=De_error_FP)) +
  geom_density() + xlim(0,1000)
Warning: Removed 930 rows containing non-finite values (stat_density).

ggplot(data = tibble(De_error_all_FP), aes(x=De_error_all_FP)) +
  geom_density() + xlim(0,1000)
Warning: Removed 14524 rows containing non-finite values (stat_density).

Error in Slope

ggplot(data = tibble(sigma_error_fromSlope_FP), aes(x=sigma_error_fromSlope_FP)) +
  geom_density() + xlim(0,1000)
Warning: Removed 8 rows containing non-finite values (stat_density).

ggplot(data = tibble(sigma_error_fromSlope_all_FP), aes(x=sigma_error_fromSlope_all_FP)) +
  geom_density() + xlim(0,1000)
Warning: Removed 13426 rows containing non-finite values (stat_density).

Error in Neighborhood Size

Using a uniform distribution is out because there is clearly a peaked distribution in the Migraine output. So I am using a quick fit to a truncated lognormal distribution

Migraine_Run2_Neighborhood_Theta

NSCI_FP
       NSCI1        NSCI2 
       67763 531462708061 
curve(dlnorm(x, meanlog = log(NS_FP), sdlog = log(7.9), log = T))

qlnorm(c(0.025,0.975),meanlog = log(NS_FP), sdlog = log(206.5))
[1] 1.062342e+01 1.260620e+10

Neighborhood_error_FP <- rlnormTrunc(n = 100000, meanlog = log(NS_FP), 
                                     sdlog = log(210), min = NSCI_FP[1], max = Inf)


ggplot(data = tibble(Neighborhood_error_FP), aes(x=Neighborhood_error_FP)) + 
  geom_density() + scale_x_log10()


sigma_error_fromNS_FP <- sqrt(Neighborhood_error_FP/(4*De_error_FP))

sigma_error_fromNS_all_FP <- sqrt(Neighborhood_error_FP/(4*De_error_all_FP))
Warning in sqrt(Neighborhood_error_FP/(4 * De_error_all_FP)) :
  NaNs produced
names(sigma_error_fromNS_FP) <- NULL

ggplot(data = tibble(sigma_error_fromNS_FP), 
       aes(x=sigma_error_fromNS_FP)) +
       geom_density() + scale_x_log10()

Plot Dispersal Kernels


kernelplot_FP <- ggplot(data.frame(x=c(0,100)),aes(x)) + 
  map(.x = sample(sigma_error_fromNS_FP,1000), .f = function(sigma){
                              stat_function(fun = dexp, args = list(rate = 1/sigma),
                                            colour = "lightblue",
                                            linetype=1,size=0.1,alpha = 0.2) }) +
    map(.x = sample(sigma_error_fromSlope_FP,1000), .f = function(sigma){
                              stat_function(fun = dexp, args = list(rate = 1/sigma),
                                            colour = "lightgreen",
                                            linetype=1,size=0.1,alpha = 0.2) }) +
  stat_function(fun=dexp,args=list(rate = 1/sigma_fromSlope_FP), linetype=2,
                              aes(color="IBD_Slope"), show.legend = T) +
  stat_function(fun=dexp,args=list(rate = 1/sigma_fromSlope_all_FP), linetype=2,
                              aes(color="IBD_Slope_1pop"), show.legend = T) +
  stat_function(fun=dexp,args=list(rate = 1/sigma_fromsigma2_FP), linetype=2,
                              aes(color="Migraine_Sigma2"), show.legend = T) +
  stat_function(fun=dexp,args=list(rate = 1/sigma_fromNS_FP), linetype=2,
                              aes(color="Migraine_Neighborhood_Size"), show.legend = T) +
  stat_function(fun=dexp,args=list(rate = 1/sigma_fromNS_all_FP), linetype=2,
                              aes(color="Migraine_Neighborhood_Size_1pop"), show.legend = T) +
  xlab("Alongshore Distance (km)") + ylab("Dispersal probability density") +
  scale_color_manual("Kernel",values = 
                    c(IBD_Slope = "green",
                      IBD_Slope_1pop = "darkgreen",
                      Migraine_Sigma2="darkblue", 
                    Migraine_Neighborhood_Size ="blue",
                    Migraine_Neighborhood_Size_1pop = "cyan4")) +
  ylim(0,0.1)


kernelplot_FP
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 3 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 2 row(s) containing missing values (geom_path).
Warning: Removed 4 row(s) containing missing values (geom_path).

Comparing Across Archipelagos


NC <- tibble(Archipelago = "New Caledonia",
            Estimate = c("Mean sampling distance",
                        "Fst ~ Distance Slope",
                        "Ne Harmonic Mean",
                        "Ne as one population",
                        "Effective Density",
                        "Effective Density one pop",
                        "Theta",
                        "Nm",
                        "g",
                        "Neighborhood Size",
                        "Neighborhood Size Low CI",
                        "Neighborhood Size High CI",
                        "Bin Width",
                        "sigma from slope",
                        "sigma from slope; Ne as one pop",
                        "sigma from NS",
                        "sigma from NS; Ne as one pop",
                        "sigma from sigma2"),
             Values = c(meandists_NC,
                        slope_NC,
                        Ne_hm_NC,
                        Ne_all_NC,
                        De_NC,
                        De_all_NC,
                        Nmu_NC,
                        Nm_NC,
                        g_NC,
                        NS_NC,
                        NSCI_NC[1],
                        NSCI_NC[2],
                        lattice2geog_NC,
                        NA,
                        NA,
                        sigma_fromNS_NC,
                        sigma_fromNS_all_NC,
                        sigma_fromsigma2_NC
                        ))

Fiji <- tibble(Archipelago = "Fiji",
            Estimate = c("Mean sampling distance",
                        "Fst ~ Distance Slope",
                        "Ne Harmonic Mean",
                        "Ne as one population",
                        "Effective Density",
                        "Effective Density one pop",
                        "Theta",
                        "Nm",
                        "g",
                        "Neighborhood Size",
                        "Neighborhood Size Low CI",
                        "Neighborhood Size High CI",
                        "Bin Width",
                        "sigma from slope",
                        "sigma from slope; Ne as one pop",
                        "sigma from NS",
                        "sigma from NS; Ne as one pop",
                        "sigma from sigma2"),
             Values = c(meandists_Fiji,
                        slope_Fiji,
                        Ne_hm_Fiji,
                        Ne_all_Fiji,
                        De_Fiji,
                        NA,
                        Nmu_Fiji,
                        Nm_Fiji,
                        g_Fiji,
                        NS_Fiji,
                        NSCI_Fiji[1],
                        NSCI_Fiji[2],
                        lattice2geog_Fiji,
                        sigma_fromSlope_Fiji,
                        NA,
                        sigma_fromNS_Fiji,
                        NA,
                        sigma_fromsigma2_Fiji
                        ))

FP <- tibble(Archipelago = "Societies",
            Estimate = c("Mean sampling distance",
                        "Fst ~ Distance Slope",
                        "Ne Harmonic Mean",
                        "Ne as one population",
                        "Effective Density",
                        "Effective Density one pop",
                        "Theta",
                        "Nm",
                        "g",
                        "Neighborhood Size",
                        "Neighborhood Size Low CI",
                        "Neighborhood Size High CI",
                        "Bin Width",
                        "sigma from slope",
                        "sigma from slope; Ne as one pop",
                        "sigma from NS",
                        "sigma from NS; Ne as one pop",
                        "sigma from sigma2"),
             Values = c(meandists_FP,
                        slope_FP,
                        Ne_hm_FP,
                        Ne_all_FP,
                        De_FP,
                        De_all_FP,
                        Nmu_FP,
                        Nm_FP,
                        g_FP,
                        NS_FP,
                        NSCI_FP[1],
                        NSCI_FP[2],
                        lattice2geog_FP,
                        sigma_fromSlope_FP,
                        sigma_fromSlope_all_FP,
                        sigma_fromNS_FP,
                        sigma_fromNS_all_FP,
                        sigma_fromsigma2_FP
                        ))            

across.archipelagos <- bind_rows(NC,Fiji,FP)

across.archipelagos.df <- dcast(across.archipelagos,Archipelago~Estimate)



#write_csv(across.archipelagos.df,"Across_archipelago_statistics.csv")
       
errors <- enframe(c(NC_NS = sigma_error_fromNS_NC,
                    NC_NS_all = sigma_error_fromNS_all_NC,
                    Fiji_NS = sigma_error_fromNS_Fiji,
                    Fiji_Slope = sigma_error_fromSlope_Fiji,
                    FP_NS = sigma_error_fromNS_FP, 
                    FP_NS_all = sigma_error_fromNS_all_FP,
                    FP_Slope = sigma_error_fromSlope_FP,
                    FP_Slope_all = sigma_error_fromSlope_all_FP),
                  name = "Archipelago", 
                  value = "Sigma") %>% 
                mutate(Archipelago = str_remove(Archipelago, pattern="\\d+$"))

violins <- ggplot(errors, aes(x = Archipelago, y = Sigma)) + geom_violin() + 
  coord_cartesian(ylim = c(5, 1000)) + 
  #geom_point(data = across.archipelagos, 
  #           mapping = aes(x = "Archipelago", y = "Sigma")) +
  scale_y_log10()

boxes <- ggplot(errors, aes(x = Archipelago, y = Sigma)) + geom_boxplot() + 
  coord_cartesian(ylim = c(5, 1000)) + 
  #geom_point(data = across.archipelagos, 
  #           mapping = aes(x = "Archipelago", y = "Sigma")) +
  scale_y_log10()

          

Make figures for the proposal

errors.p <- enframe(c(`New Caledonia` = sigma_error_fromNS_NC,
                    Fiji = sigma_error_fromSlope_Fiji,
                    Societies = sigma_error_fromSlope_FP),
                  name = "Archipelago", 
                  value = "Sigma") %>% 
                mutate(Archipelago = str_remove(Archipelago, pattern="\\d+$"))

#create a tibble with the point estimates of interest
point_estimates <- across.archipelagos.df %>%  select("Archipelago","sigma from slope") %>% 
  mutate(`sigma from slope` = replace(`sigma from slope`,2,across.archipelagos.df$`sigma from NS`[2])) 


violins.p <- errors.p %>% remove_missing() %>% 
  mutate(Archipelago = factor(Archipelago,levels = c("New Caledonia","Fiji","Societies"))) %>% 
  ggplot() + geom_violin(mapping = aes(x = Archipelago, y = Sigma)) + 
 geom_point(data = point_estimates, 
             mapping = aes(x = Archipelago, y = `sigma from slope`), color = "grey", size = 5) +
  ylim(0,1000) +
    coord_cartesian(ylim = c(1, 1000)) + 
  scale_y_log10()

ggsave("Daruanus_archipelagos_violins.pdf",violins.p)



kernelplot_archipelagos <- ggplot(data.frame(x=c(0,250)),aes(x)) + 
  map(.x = sample(sigma_error_fromNS_NC,500), .f = function(sigma){
                              stat_function(fun = dexp, args = list(rate = 1/sigma),
                                            colour = "palevioletred",
                                            linetype=1,size=0.1,alpha = 0.1) }) +
 map(.x = sample(sigma_error_fromSlope_Fiji,500), .f = function(sigma){
                             stat_function(fun = dexp, args = list(rate = 1/sigma),
                                           colour = "goldenrod",
                                           linetype=1,size=0.1,alpha = 0.1) }) +
 map(.x = sample(sigma_error_fromSlope_FP,500), .f = function(sigma){
                              stat_function(fun = dexp, args = list(rate = 1/sigma),
                                            colour = "lightblue",
                                            linetype=1,size=0.1,alpha = 0.1) }) +
  stat_function(fun=dexp,args=list(rate = 1/sigma_fromNS_NC), linetype=1,
                              aes(color="New Caledonia"), show.legend = T) +
  stat_function(fun=dexp,args=list(rate = 1/sigma_fromSlope_Fiji), linetype=1,
                              aes(color="Fiji"), show.legend = T) +
  stat_function(fun=dexp,args=list(rate = 1/sigma_fromSlope_FP), linetype=1,
                              aes(color="Societies"), show.legend = T) +
  xlab("Alongshore Distance (km)") + ylab("Dispersal probability density") +
  scale_color_manual("Archipelago",values = 
                    c(`New Caledonia` = "red",
                      Fiji = "orange",
                      Societies="blue" 
                   )) +
  ylim(0,0.02)

#ggsave("Darunaus_archipelagos_kernels.pdf", kernelplot_archipelagos)
Do, C., R. S. Waples, D. Peel, G. M. Macbeth, B. J. Tillett, and J. R. Ovenden. 2014. NeEstimator V2: Re-Implementation of Software for the Estimation of Contemporary Effective Population Size from Genetic Data.” Molecular Ecology Resources 14 (1): 209–14. https://doi.org/f5k7mz.
Jones, A. T., J. R. Ovenden, and Y.-G. Wang. 2016. “Improved Confidence Intervals for the Linkage Disequilibrium Method for Estimating Effective Population Size.” Heredity 117 (4): 217–23. https://doi.org/f9fbj8.
Leblois, Raphaël, and François Rousset. 2020. MigraiNe 0.6 Manual.”
Neel, M. C., K. McKelvey, N. Ryman, M. W. Lloyd, R. Short Bull, F. W. Allendorf, M. K. Schwartz, and R. S. Waples. 2013. “Estimation of Effective Population Size in Continuously Distributed Populations: There Goes the Neighborhood.” Heredity, May, 1–11. https://doi.org/10.1038/hdy.2013.37.
Pinsky, Malin L., Humberto R. Montes, and Stephen R. Palumbi. 2010. “Using Isolation by Distance and Effective Density to Estimate Dispersal Scales in Anemonefish.” 64 (9): 2688–2700. https://doi.org/czskhg.
Pinsky, Malin L., Pablo Saenz-Agudelo, Océane C. Salles, Glenn R. Almany, Michael Bode, Michael L. Berumen, Serge Andréfouët, Simon R. Thorrold, Geoffrey P. Jones, and Serge Planes. 2017. “Marine Dispersal Scales Are Congruent over Evolutionary and Ecological Time.” Current Biology : CB, December, 1–16. https://doi.org/10.1016/j.cub.2016.10.053.
Rousset, F. 1997. Genetic Differentiation and Estimation of Gene Flow from F-statistics Under Isolation by Distance. Genetics 145 (4): 1219–28.
Waples, Robin S. 2014. “Testing for Hardy: Have We Lost the Plot?” Journal Of Heredity 106 (1): 1–19. https://doi.org/10.1093/jhered/esu062.
Waples, Robin S., Tiago Antao, and Gordon Luikart. 2014. “Effects of Overlapping Generations on Linkage Disequilibrium Estimates of Effective Population Size.” Genetics 197 (2): 769–80. https://doi.org/10.1534/genetics.114.164822.
Waples, Robin S., and Chi Do. 2010. “Linkage Disequilibrium Estimates of Contemporary N-e Using Highly Variable Genetic Markers: A Largely Untapped Resource for Applied Conservation and Evolution.” Evolutionary Applications 3 (3): 244–62. https://doi.org/10.1111/j.1752-4571.2009.00104.x.
LS0tCnRpdGxlOiAiRGFzY3lsbHVzIGFydWFudXMgSUJEIENhbGN1bGF0aW9ucyIKb3V0cHV0OgogIHBkZl9kb2N1bWVudDoKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6ICc0JwogICAgbGF0ZXhfZW5naW5lOiB4ZWxhdGV4CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDQKICAgIHRvY19mbG9hdDogeWVzCiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6ICc0JwogICAgZGZfcHJpbnQ6IHBhZ2VkCmJpYmxpb2dyYXBoeTogIi4uL0lCRF9LZXJuZWxzLmJpYiIKLS0tCmBgYHtyIHNldHVwLCBlY2hvID0gRiwgbWVzc2FnZSA9IEZ9CgpsaWJyYXJ5KHJlYWR4bCkKbGlicmFyeShhZGVnZW5ldCkKbGlicmFyeShnZGlzdGFuY2UpCmxpYnJhcnkocGVnYXMpCmxpYnJhcnkoaGllcmZzdGF0KQpsaWJyYXJ5KHJhc3RlcikKbGlicmFyeShyZ2RhbCkKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ3JhcGg0bGcpCmxpYnJhcnkoY29kYSkKbGlicmFyeShrbml0cikKbGlicmFyeShmb3JjYXRzKQpsaWJyYXJ5KHN0cmF0YUcpCmxpYnJhcnkoRW52U3RhdHMpCgpzb3VyY2UoIi4uL0lCRF9mdW5jdGlvbnMuUiIpCmtuaXRyOjpvcHRzX2tuaXQkc2V0KHJvb3QuZGlyID0gJy4vRGFydWFudXMnKQoKCmBgYAoKCkNlY2lsZSBGYXV2ZWxvdCBoYXMga2luZGx5IHNoYXJlZCBhIGdpYW50IChuPTEzNTgpIG1pY3Jvc2F0ZWxsaXRlIGRhdGFzZXQgZm9yICpEYXNjeWxsdXMgYXJ1YW51cyosIHRoZSB3aGl0ZSB0YWlsZWQgb3IgaHVtYnVnIGRhbXNlbC4gV2UgZG9uJ3QgaGF2ZSBhbiBlbXBpcmljYWwgcGFyZW50YWdlIGtlcm5lbCBmb3IgdGhpcyBzcGVjaWVzLCBidXQgc2hlIGRvZXMgaGF2ZSBzYW1wbGVzIGZyb20gTmV3IENhbGVkb25pYSBhbmQgRmlqaSB3aGljaCBhcmUgdHdvIG9mIHRoZSBhcmNoaXBlbGFnb3MgaW4gb3VyIHByb3Bvc2FsLiBTaGUgYWxzbyBoYXMgdGhlbSBmcm9tIEZyZW5jaCBQb2x5bmVzaWEgYW5kIFBhcHVhIE5ldyBHdWluZWEuIFNvIHRoZSBnb2FsIGhlcmUgaXMgdG8gZG8gYSBwcmVsaW1pbmFyeSBhbmFseXNpcyBmb3IgdGhlIHNha2Ugb2YgdGhlIHByb3Bvc2FsLiBPbmUgcHJvYmxlbSB3aWxsIGJlIHRoYXQgdGhlc2UgYXJlIGxpa2VseSBhZHVsdHMsIG5vdCBuZXcgcmVjcnVpdHMuLi4KCiFbV2hpdGUgVGFpbGVkIERhbXNlbF0oZmlndXJlcy9IdW1idWdfZGFzY3lsbHVzLmpwZykKCgoKIVtTYW1wbGUgU2l0ZXNdKGZpZ3VyZXMvRGFfc2FtcGxlc2l0ZXMuanBnKQoKIyBSZWFkIGFuZCBjb252ZXJ0IGRhdGEKCkhhZCB0byBkbyBhIGxpdHRsZSBjb252ZXJzaW9uIGluIGJiZWRpdCB0byByZWFkeSB0aGUgRXhjZWwgZm9ybWF0dGVkIGRhdGEgZm9yIGlucHV0IGludG8gUgoKIyMgUmVhZCBpbiB0aGUgZGF0YQoKYGBge3IgcmVhZGRhdGEsIG1lc3NhZ2UgPSBGfQojcmVhZCBpbiB0aGUgZGF0YQpEYXJ1YW51cy5nZW4gPC0gcmVhZC5nZW5lcG9wKCJEYXJ1YW51c19GYXV2ZWxvdC5nZW4iLCBuY29kZSA9IDNMKQojIHJlbmFtZSB0aGUgcG9wdWxhdGlvbnMgdG8ganVzdCB0aGUgdGV4dCB2YWx1ZXMKRGFydWFudXMuZ2VuQHBvcCA8LSBEYXJ1YW51cy5nZW5AcG9wICU+JSBzdHJfZXh0cmFjdCgiW0EtWmEtel0rIikgJT4lIGFzLmZhY3RvcigpCgojIHJlYWQgaW4gdGhlIGxvY2FsaXR5IGluZm9ybWF0aW9uCkRhcnVhbnVzLnNpdGVzIDwtIHJlYWRfZXhjZWwoIkRhcnVhbnVzX3NpdGVzLnhsc3giKQoKRGFydWFudXMuZ2VuQHBvcCAlPiUgdGliYmxlKHBvcCA9IGFzLmNoYXJhY3RlciguKSkgJT4lIGNvdW50KHBvcCkKCmBgYAoKIyMgVGVzdCBmb3IgSFdFCgpUZXN0IGZvciBIV0UuIEZpcnN0IGxvb2sgYXQgdGhlIG51bWJlciBvZiBwb3B1bGF0aW9ucyB0aGF0IGhhdmUgSFdFIGRlcGFydHVyZXMgZm9yIGVhY2ggbG9jdXMuIFRoZW4gbG9vayBhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIHAtdmFsdWVzIGZvbGxvd2luZyBbQHdhcGxlc1Rlc3RpbmdIYXJkeVdlaW5iZXJnMjAxNF0uIEEgZmxhdCBkaXN0cmlidXRpb24gaXMgZmluZSwgYnV0IGVucmljaG1lbnQgZm9yIGxvdyBwLXZhbHVlcyBzdWdnZXN0cyB0aGF0IHRoZSBsb2N1cyBpcyBub3QgZ2xvYmFsbHkgYXQgSFdFLgoKYGBge3IgSFdFfQoKc2VwYXJhdGVkX3BvcHMgPC0gc2VwcG9wKERhcnVhbnVzLmdlbikKCiMgcGVyZm9ybSBIV0UgdGVzdApodyA8LSBtYXAoc2VwYXJhdGVkX3BvcHMsIGh3LnRlc3QpCiAKaHcyIDwtIGRvLmNhbGwocmJpbmQsaHcpICU+JSBhc190aWJibGUocm93bmFtZXMgPSAibG9jdXMiKSAlPiUgIGdyb3VwX2J5KGxvY3VzKSAlPiUKICAgICAgICBzdW1tYXJpemUob3V0b2Zod2UgPSBsZW5ndGgod2hpY2goUHIuZXhhY3QgPCAwLjA1KSksIAogICAgICAgICAgICAgICAgICBvdXRvZmh3ZV9wcm9wID0gbGVuZ3RoKHdoaWNoKFByLmV4YWN0IDwgMC4wNSkpL2xlbmd0aChodyksCiAgICAgICAgICAgICAgICAgIG1lYW5wID0gbWVhbihQci5leGFjdCkpCgpodzIKCgpwdmFsdWVzPC0gZG8uY2FsbChyYmluZCxodykgJT4lIGFzX3RpYmJsZShyb3duYW1lcyA9ICJsb2N1cyIpICU+JSAgZ3JvdXBfYnkobG9jdXMpICU+JSAKICAgICAgICAgIGdncGxvdChhZXMoeD1Qci5leGFjdCkpICsgZ2VvbV9oaXN0b2dyYW0oYmlucz0xMCkgKyBmYWNldF93cmFwKH5sb2N1cykKCnB2YWx1ZXMKCmBgYApJdCdzIHByZXR0eSBjbGVhciB3ZSBuZWVkIHRvIHphcCBsb2NpIDQwOCwgNDk0LCBhbmQgNTkzLiA1NjUgaXMgYSBsaXR0bGUgd2VpcmQsIGJ1dCBsZXQncyBrZWVwIGl0LgoKYGBge3J9CmxvY05hbWVzKERhcnVhbnVzLmdlbikKCkRhcnVhbnVzLmdlbiA8LSBEYXJ1YW51cy5nZW5bbG9jPS1jKDIsNSwxMCldCgojY29udmVydCB0byBzdHJhdGFHIGd0eXBlcwpEYXJ1YW51cy5ndHlwZXMgPC0gZ2VuaW5kMmd0eXBlcyhEYXJ1YW51cy5nZW4pCgojZ2VuaW5kX3RvX2dlbmVwb3AoRGFydWFudXMuZ2VuLCBvdXRwdXQgPSAiRGFydWFudXMvRGFydWFudXNfQWxsXzhsb2N1cy50eHQiKQpgYGAKIyMgU3BsaXQgYnkgQXJjaGlwZWxhZ28KCmBgYHtyfQojc3BsaXQgdGhlbSBhZ2FpbgpzZXBhcmF0ZWRfcG9wcyA8LSBzZXBwb3AoRGFydWFudXMuZ2VuKQoKI3NwbGl0IG9mZiB0aGUgRmlqaSBzYW1wbGVzCmZpamlwb3BzIDwtIERhcnVhbnVzLnNpdGVzICU+JSBmaWx0ZXIoUmVnaW9uPT0iRmlqaSIpCkRhcnVhbnVzLkZpamkgPC0gcmVwb29sKHNlcGFyYXRlZF9wb3BzW2Zpamlwb3BzJEFiYnJdKQoKI3NwbGl0IG9mZiB0aGUgTkMgc2FtcGxlcwpOQ3BvcHMgPC0gRGFydWFudXMuc2l0ZXMgJT4lIGZpbHRlcihSZWdpb249PSJOQyIpICU+JSBmaWx0ZXIoQWJiciE9IkhpZSIpCkRhcnVhbnVzLk5DIDwtIHJlcG9vbChzZXBhcmF0ZWRfcG9wc1tOQ3BvcHMkQWJicl0pCgojc3BsaXQgb2ZmIHRoZSBGUCBzYW1wbGVzCkZQcG9wcyA8LSBEYXJ1YW51cy5zaXRlcyAlPiUgZmlsdGVyKFJlZ2lvbiA9PSAiRlAiKSAlPiUgCiAgZmlsdGVyKEFiYnIgJWluJSBjKCJQdW5hIiwiVGV0aWEiLCAiVGVtIiwiTW8iLCJUYWhhYSIpKQpEYXJ1YW51cy5GUCA8LSByZXBvb2woc2VwYXJhdGVkX3BvcHNbRlBwb3BzJEFiYnJdKQoKCgoKI2dlbmluZF90b19nZW5lcG9wKERhcnVhbnVzLk5DLG91dHB1dCA9ICJEYXJ1YW51cy9OQy9EYXJ1YW51c19OQy50eHQiKQojZ2VuaW5kX3RvX2dlbmVwb3AoRGFydWFudXMuRmlqaSxvdXRwdXQgPSAiRGFydWFudXMvRmlqaS9EYXJ1YW51c19GaWppLnR4dCIpCiNnZW5pbmRfdG9fZ2VuZXBvcChEYXJ1YW51cy5GUCxvdXRwdXQgPSAiRGFydWFudXMvRlAvRGFydWFudXNfRlAudHh0IikKYGBgCgojIyBDYWxjdWxhdGUgRWZmZWN0aXZlIFNpemUKCgogQG5lZWxFc3RpbWF0aW9uRWZmZWN0aXZlUG9wdWxhdGlvbjIwMTMgc2F5OgoKPiBPdXIgcmVzdWx0cyBzaG93IHRoYXQgdGhlIExEIG1ldGhvZCBwcm92aWRlcyBhIGdvb2QgYXBwcm94aW1hdGlvbiBvZiB0aGUgTlMgYXMgbG9uZyBhcyB0aGUgc2NhbGUgb2Ygc2FtcGxpbmcgaXMgY29tbWVuc3VyYXRlIHdpdGggdGhlIHNjYWxlIG9mIGxvY2FsIGJyZWVkaW5nLgoKVHJlYXRpbmcgdGhlIHdob2xlIGRhdGFzZXQgYXMgb25lIHBvcHVsYXRpb24geWllbGRzICROX2UkIG9mIC0yNzQyMy45IChpbiBvdGhlciB3b3JkcyB0b28gbGFyZ2UpIGF0IHBjcml0IG9mIDAuMDIuIEJ1dCB0aGUgcHJvYmxlbSBpcyBkZXRlcm1pbmluZyB0aGUgc2l6ZSBvZiB0aGUgZ2VuZXRpYyBuZWlnaGJvcmhvb2QsIGJlY2F1c2UgRmF1dmVsb3QgZXQgYWwuJ3Mgc2FtcGxlcyB3ZXJlIG5vdCBhcyByZWd1bGFybHkgc3BhY2VkIGFzIEQnQWxvaWEncy4gCgoKR29pbmcgdG8gdXNlIHRoZSBMRCBtZXRob2QgYXMgbW9zdCByZWNlbnRseSBkaXNjdXNzZWQgYnkgQHdhcGxlc0xpbmthZ2VEaXNlcXVpbGlicml1bUVzdGltYXRlczIwMTAsIGFuZCBpbXBsZW1lbnRlZCBpbiBOZUVzdGltYXRvciB2MiBbQGRvTmVFc3RpbWF0b3JWMlJlaW1wbGVtZW50YXRpb24yMDE0XS4gSSdtIGdvaW5nIHRvIHJlbW92ZSBhbGxlbGVzIGZvbGxvd2luZyBXYXBsZXMgYW5kIERvJ3MgcnVsZSBvZiB0aHVtYi4gUGFyYW1ldGVyIHNldHRpbmdzIGFyZSBpbiBgIkRhcnVhbnVzL05lX2VzdGltYXRvci8iYCBCZXN0IHRvIHJ1biB0aGlzIGZyb20gdGhlIGNvbW1hbmQgbGluZSBhY3R1YWxseS4gSSBhbSBoYXZpbmcgaXQgY2FsY3VsYXRlICROX2IkIChudW1iZXIgb2YgYnJlZWRlcnMpIGZvciBtb25vZ2FteSwgYXMgdGhlIHByb3RvZ3lub3VzIG1hdGluZyBzeXN0ZW0gb2YgKkRhc2N5bGx1cyBhcnVhbnVzKiBzZWVtcyBjbG9zZXIgdG8gbW9ub2dhbXkgdGhhbiByYW5kb20gbWF0aW5nLiAgQWxzbyBoYWQgdG8gZWRpdCB0aGUgdGFibGUgb3V0cHV0IG9mIE5lRXN0aW1hdG9yIHRvIG1ha2UgaXQgbGVnaWJsZSB0byBSIGJlY2F1c2UgaXQgaGFkIGxvdHMgb2Ygc3BhY2VzIGFuZCBlbXB0eSBjZWxscyBgciBlbW86OmppKCItMSIpYAoKYGBge2Jhc2ggTmVFc3RpbWF0b3IsIGV2YWwgPSBGLCBtZXNzYWdlPUZ9Ci9BcHBsaWNhdGlvbnMvTmVFc3RpbWF0b3IvTmUyLTFNIGk6L1VzZXJzL2VyaWMvZ2l0aHViL0lCRF9LZXJuZWxzL0RhcnVhbnVzL05lRXN0aW1hdG9yL2luZm8gbzovVXNlcnMvZXJpYy9naXRodWIvSUJEX0tlcm5lbHMvRGFydWFudXMvTmVFc3RpbWF0b3Ivb3B0aW9uCgpJTkZPCjEgIAkqIEEgbnVtYmVyID0gc3VtIG9mIG1ldGhvZChzKSB0byBydW46IExEKD0xKSwgSGV0KD0yKSwgQ29hbig9NCksIFRlbXBvcmFsKD04KS4KL1VzZXJzL2VyaWMvZ2l0aHViL0lCRF9LZXJuZWxzL0RhcnVhbnVzLyAJKiBJbnB1dCBEaXJlY3RvcnkKRGFydWFudXNfQWxsXzhsb2N1cy50eHQJKiBJbnB1dCBmaWxlIG5hbWUKMiAJCQkqIDEgPSBGU1RBVCBmb3JtYXQsIDIgPSBHRU5FUE9QIGZvcm1hdAovVXNlcnMvZXJpYy9naXRodWIvSUJEX0tlcm5lbHMvRGFydWFudXMvTmVFc3RpbWF0b3IvIAkqIE91dHB1dCBEaXJlY3RvcnkKRGFydWFudXNfTEROZS50eHQgCSogT3V0cHV0IGZpbGUgbmFtZSAocHV0IGFzdGVyaXNrIGFkamFjZW50IHRvIHRoZSBuYW1lIHRvIGFwcGVuZCkKNiAJCQkqIE51bWJlciBvZiBjcml0aWNhbCB2YWx1ZXMsIGFkZGVkIDEgaWYgYSBydW4gYnkgcmVqZWN0aW5nIG9ubHkgc2luZ2xldG9uIGFsbGVsZXMgaXMgaW5jbHVkZWQKMSAwLjAxIDAuMDIgMC4wMyAwLjA0IDAuMDUgICAJKiBDcml0aWNhbCB2YWx1ZXMsIGEgc3BlY2lhbCB2YWx1ZSAnMScgaXMgZm9yIHJlamVjdGluZyBvbmx5IHNpbmdsZXRvbiBhbGxlbGVzCjEgCQkqIDA6IFJhbmRvbSBtYXRpbmcsIDE6IE1vbm9nYW15IChMRCBtZXRob2QpCgoKT1BUSU9OCjEgIDEgIDUgIDEgCSogRmlyc3QgbnVtYmVyID0gc3VtIG9mIG1ldGhvZChzKSB0byBoYXZlIGV4dHJhIG91dHB1dDogTEQoPTEpLCBIZXQoPTIpLCBDb2FuKD00KSwgVGVtcG9yYWwoPTgpCjAgCSogTWF4aW11bSBpbmRpdmlkdWFscy9wb3AuIElmIDA6IG5vIGxpbWl0CjAgCSogRmlyc3QgZW50cnkgbjEgPSAwOiBObyBGcmVxIG91dHB1dC4gSWYgbjEgPSAtMTogRnJlcS4gb3V0cHV0IHVwIHRvIHBvcHVsYXRpb24gNTAuIFR3byBlbnRyaWVzIG4xLCBuMiB3aXRoIG4xIDw9IG4yOiBGcmVxIG91dHB1dCBmb3IgcG9wdWxhdGlvbnMgZnJvbSBuMSB0byBuMi4gTWF4LiBwb3B1bGF0aW9ucyB0byBoYXZlIEZyZXEgb3V0cHV0IGlzIHNldCBhdCA1MAowIAkqIEZvciBCdXJyb3cgb3V0cHV0IGZpbGUgKHVwIHRvIDUwIHBvcHVsYXRpb25zIGNhbiBoYXZlIG91dHB1dCkuIFNlZSByZW1hcmsgYmVsb3cKMSAJKiBQYXJhbWV0ZXIgQ0k6IDEgZm9yIFllcywgMCBmb3IgTm8KMSAJKiBKYWNra25pZmUgQ0k6IDEgZm9yIFllcywgMCBmb3IgTm8KMCAJKiBVcCB0byBwb3B1bGF0aW9uLCBvciByYW5nZSBvZiBwb3B1bGF0aW9ucyB0byBydW4gKGlmIDIgZW50cmllcykuIElmIGZpcnN0IGVudHJ5ID0gMDogbm8gcmVzdHJpY3Rpb24KMCAJKiBBbGwgbG9jaSBhcmUgYWNjZXB0ZWQKMSAJKiBFbnRlciAxOiBBIGZpbGUgaXMgY3JlYXRlZCB0byBkb2N1bWVudCBtaXNzaW5nIGRhdGEgaWYgdGhlcmUgYXJlIGFueSBpbiBpbnB1dCBmaWxlLiBFbnRlciAwOiBubyBmaWxlIGNyZWF0ZWQKMCAgCSogTGluZSBmb3IgY2hyb21vc29tZXMvbG9jaSBvcHRpb24gYW5kIGZpbGUKCgoKYGBgCgoKSSBpbXBsZW1lbnRlZCBhIGZpbHRlcmluZyBzdGVwIHRoYXQgZm9sbG93cyBAd2FwbGVzTGlua2FnZURpc2VxdWlsaWJyaXVtRXN0aW1hdGVzMjAxMCA6Cgo+IEZvciBTIFw+IDEwMDogY2hvb3NlIFBjcml0ID0gMC4wMQo+IEZvciBTIFw+IDI1OiBjaG9vc2UgUGNyaXQgPSAwLjAyLlwKPiBGb3IgUyBcPCAyNTogY2hvb3NlIHNvIHRoYXQgMS8oMlMpIFw8IFBjcml0IFw8IDEvUy4KCgpBbmQgSSBhbSBvbmx5IGtlZXBpbmcgZXN0aW1hdGVzIGZyb20gc2FtcGxlcyB3aXRoIG4gPj0gMTAuCgpgYGB7UiBOZUVzdGltYXRvcl9vdXRwdXR9Ck5lX2VzdGltYXRlcyA8LSByZWFkX05lRXN0aW1hdG9yKGZpbGUgPSAiLi9OZUVzdGltYXRvci9EYXJ1YW51c19MRE5lX3hMRC50eHQiKQoKIyBmaWx0ZXJpbmcgYmFzZWQgb24gcnVsZSBvZiB0aHVtYiBmcm9tIFdhcGxlcyAmIERvCk5lX2VzdGltYXRlc19mIDwtIFdERmlsdGVyKE5lX2VzdGltYXRlcywgMTApICU+JSAKICBtdXRhdGUoUG9wdWxhdGlvbiA9IHN0cl9yZXBsYWNlKFBvcHVsYXRpb24scGF0dGVybiA9ICJcXGQrXFw6KFxcdyspX1tcXHctXSsiLCByZXBsYWNlbWVudCA9ICJcXDEiICkpCgpgYGAKCgoKIyMjIEludGVycHJldGluZyBMRCBFZmZlY3RpdmUgU2l6ZQoKVGhlc2UgZXN0aW1hdGVzIGFyZSB0cnVlIE5lIGVzdGltYXRlcyBiZWNhdXNlIHRoZXNlIHNhbXBsZXMgd2VyZSB0YWtlbiBhY3Jvc3MgdGhlIGFnZSBzdHJ1Y3R1cmUgb2YgdGhlIHBvcHVsYXRpb24uIFNvIHRoZXJlIHdvbid0IGJlIGFueSBjb252ZXJzaW9uIGZyb20gTmIgdG8gTmUuCgpDZWNpbGUgc2F5czoKPiBGb3IgRmlqaSBhbmQgTkMsIG11bHRpcGxlIGluZGl2aWR1YWxzIGF0IGEgY29yYWwgY29sb255IHdlcmUgaW5kZWVkIHNhbXBsZWQgYXMgd2UgdXNlZCBjbG92ZSBvaWwgYXJvdW5kIGNvcmFsIGNvbG9uaWVzIGNvdmVyZWQgYnkgYSBwbGFzdGljIGJhZy4uLiBzbyB5ZXMgdG9vLCBhY3Jvc3MgYWdlIHN0cnVjdHVyZS4gSSBkbyBub3QgaGF2ZSB0aGUgc2l6ZSBvZiBpbmRpdmlkdWFscyBzYW1wbGVkCgpbQHdhcGxlc0VmZmVjdHNPdmVybGFwcGluZ0dlbmVyYXRpb25zMjAxNF0gc2F5czoKCj5PdXIgZW1waXJpY2FsIHJlc3VsdHMgcHJvdmlkZSBzb21lIHF1YWxpZmllZCBzdXBwb3J0IGZvciB0aGUgaHlwb3RoZXNpcyAoV2FwbGVzIGFuZCBEbyAyMDEwKSB0aGF0IGEgc2FtcGxlIHRoYXQgaW5jbHVkZXMgYXMgbWFueSBjb2hvcnRzIGFzIHRoZXJlIGFyZSBpbiBhIGdlbmVyYXRpb24gc2hvdWxkIHByb2R1Y2UgYW4gZXN0aW1hdGUgYXBwcm94aW1hdGVseSBlcXVhbCB0byBOZS4uLi5BbGwgZXN0aW1hdGVzIGJhc2VkIG9uIHJhbmRvbSBzYW1wbGVzIG9mIGFkdWx0cyB3ZXJlIHNtYWxsZXIgdGhhbiB0cnVlIE5lIC4uLiwgYnV0IHRoZXJlIHdhcyBhIHRlbmRlbmN5IGZvciB0aGUgYmlhcyB0byBiZSBsZXNzIHdoZW4gdGhlIG51bWJlciBvZiBjb2hvcnRzIGluY2x1ZGVkIGluIHRoZSBhZHVsdCBzYW1wbGUgY29ycmVzcG9uZGVkIG1vcmUgY2xvc2VseSB0byB0aGUgZ2VuZXJhdGlvbiBsZW5ndGguCgoqRGFzY3lsbHVzIGFydWFudXMqIHN0cmlrZXMgbWUgYXMgb25lIG9mIHRob3NlIHNwZWNpZXMgd2hlcmUgeW91J2xsIGhhdmUgYXMgbWFueSBjb2hvcnRzIGFzIGdlbmVyYXRpb25zLCBhbHRob3VnaCBwcm90b2d5bnkga2luZCBvZiBtZXNzZXMgd2l0aCB0aGlzLiBJbiBhbnkgY2FzZSwgd2UgY2FuIGV4cGVjdCBvdXIgZXN0aW1hdGVzIG9mIE5lIChhbmQgdGh1cyBEZSkgdG8gYmUgZG93bndhcmRseSBiaWFzZWQsIGFuZCB0aGVyZWZvcmUgb3VyIGVzdGltYXRlcyBvZiAkXHNpZ21hJCB0byBiZSB1cHdhcmRseSBiaWFzZWQsIGJ5IGhvcGVmdWxseSBsZXNzIHRoYW4gMTAlPwoKIyBOZXcgQ2FsZWRvbmlhCgojIyBUcmFkaXRpb25hbCBJc29sYXRpb24gYnkgRGlzdGFuY2UgTWV0aG9kCgpCYXNlZCBvbiB0aGUgT0cgW0Byb3Vzc2V0R2VuZXRpY0RpZmZlcmVudGlhdGlvbkVzdGltYXRpb24xOTk3XSBlc3RpbWF0b3IgZnJvbSBzbG9wZSBvZiB0aGUgSUJEIHJlZ3Jlc3Npb24uCgojIyMgQ2FsY3VsYXRlIGRpc3RhbmNlIG1hdHJpY2VzCgpXZWlyIGFuZCBDb2NrZXJoYW0ncyBGc3QgYW5kIG90aGVyIGJhc2ljIHN0YXRzCgpgYGB7ciBGU1R9CgpEYXJ1YW51cy5OQy5oZnN0IDwtIGdlbmluZDJoaWVyZnN0YXQoRGFydWFudXMuTkMpCkRhcnVhbnVzLk5DLmxvY2kgPC0gZ2VuaW5kMmxvY2koRGFydWFudXMuTkMpCiNnZW4ubG9jaSA8LSBnZW5pbmQybG9jaShnZW4pCnN0YXRzLk5DIDwtIGJhc2ljLnN0YXRzKERhcnVhbnVzLk5DKQp0aGV0YS5OQyA8LSB0aGV0YS5tc2F0KERhcnVhbnVzLk5DLmxvY2kpCiNtZWFuIHRoZXRhCm1lYW4odGhldGEuTkNbLDJdKQpmc3QuTkMgPC0gZ2VuZXQuZGlzdChEYXJ1YW51cy5OQy5oZnN0LCBtZXRob2QgPSAiV0M4NCIpCiMgbWVhbiBGaXMgdmFsdWVzCnN0YXRzLk5DJEZpcyAlPiUgYXNfdGliYmxlKCkgJT4lIHN1bW1hcml6ZShhY3Jvc3MoZXZlcnl0aGluZygpLG1lYW4sIG5hLnJtPVRSVUUpKQoKbWVhbkZpcyA8LSBzdGF0cy5OQyRGaXMgJT4lIGFzX3RpYmJsZSgpICU+JSBzdW1tYXJpemUoYWNyb3NzKGV2ZXJ5dGhpbmcoKSxtZWFuLCBuYS5ybT1UUlVFKSkgJT4lIHN1bW1hcml6ZShtZWFuRmlzID0gcm93TWVhbnMoLikpCiMgbGluZWFyaXplCmZzdC5OQyA8LSBmc3QuTkMvKDEtZnN0Lk5DKQoKCiNjYWxjdWxhdGUgZ3JlYXQgY2lyY2xlIGRpc3RhbmNlCmdjZGlzdHNfTkMgPC0gYXMuZGlzdChwb2ludERpc3RhbmNlKE5DcG9wc1ssNTo0XSwgbG9ubGF0PVQpLzEwMDApCmF0dHIoZ2NkaXN0c19OQywgIkxhYmVscyIpIDwtIE5DcG9wcyRBYmJyCmdjZGlzdHMubWF0X05DIDwtIGFzLm1hdHJpeChnY2Rpc3RzX05DKQojd3JpdGUuY3N2KGFzLm1hdHJpeChnZW4uZnN0KSwgIkRhcnVhbnVzX2xpbmVhcml6ZWRGc3QuY3N2Iiwgcm93Lm5hbWVzID0gRiwgcXVvdGU9RikKI3dyaXRlLmNzdihhcy5tYXRyaXgoZ2NkaXN0cyksICJEYXJ1YW51c19nY2Rpc3RzLmNzdiIsIHJvdy5uYW1lcyA9IEYsIHF1b3RlPUYpCgojcHVsbCBvdXQgYSBmZXcgb3RoZXIgZGlzdGFuY2VzIHdlJ2xsIG5lZWQKbmVpZ2hib3JkaXN0c19OQyA8LSBnY2Rpc3RzLm1hdF9OQ1tyb3coZ2NkaXN0cy5tYXRfTkMpID09IGNvbChnY2Rpc3RzLm1hdF9OQykgKyAxXQpkaXN0ZnJvbVAxX05DIDwtIGdjZGlzdHMubWF0X05DWywxXQptYXhkaXN0X05DIDwtIG1heChnY2Rpc3RzLm1hdF9OQykKbWVhbmRpc3RzX05DIDwtIG1lYW4obmVpZ2hib3JkaXN0c19OQykKCgpgYGAKCgojIyMgQ3JlYXRlIERpc3BlcnNhbCBLZXJuZWwKCgojIyMjIENhbGN1bGF0ZSBsaW5lYXIgbW9kZWwKCkZpcnN0IHRvIGdldCB0aGUgc2xvcGUgJG0kIHdlIG5lZWQgdG8gbWFrZSBhIHNpbXBsZSBsaW5lYXIgbW9kZWwuIEkgZG9uJ3QgdGhpbmsgc2lnbmlmaWNhbmNlIGlzIHJlYWxseSBpbXBvcnRhbnQgaGVyZSwgYnV0IHdlIGNhbiBjYWxjdWxhdGUgdGhhdCB3aXRoIGEgTWFudGVsIHRlc3QuCgpgYGB7ciBJQkR9CiMgbWFudGVsIHRlc3QKbWFudGVsdCA8LSBtYW50ZWwucmFuZHRlc3QoZnN0Lk5DLGdjZGlzdHNfTkMsIG5yZXBldCA9IDEwMDAwKQoKZGlzdGFuY2VzIDwtIHRpYmJsZShkaXN0YW5jZT1hcy52ZWN0b3IoZ2NkaXN0c19OQyksZnN0PWFzLnZlY3Rvcihmc3QuTkMpKQoKbG1vZGVsX05DIDwtIGxtKGZzdCB+IGRpc3RhbmNlICwgZGlzdGFuY2VzKQoKc2xvcGVfTkMgPC0gcm91bmQobG1vZGVsX05DJGNvZWZmaWNpZW50c1syXSw3KQptYW50ZWxyIDwtIHJvdW5kKG1hbnRlbHQkb2JzLCAyKQpwdmFsdWUgPC0gcm91bmQobWFudGVsdCRwdmFsdWUsIDUpCgpsbW9kZWxfcGxvdF9OQyA8LSBnZ3Bsb3QoZGlzdGFuY2VzLGFlcyh4PWRpc3RhbmNlLHk9ZnN0KSkgKwogICAgICAgICAgICAgICAgZ2VvbV9wb2ludCgpICsgZ2VvbV9zbW9vdGgobWV0aG9kPWxtKSArIHhsYWIoIkdlb2dyYXBoaWMgRGlzdGFuY2UgKGttKSIpICsgCiAgICAgICAgICAgICAgICB5bGFiKGV4cHJlc3Npb24oRlsiU1QiXS8xLUZbIlNUIl0pKSArIAogICAgICAgICAgICAgICAgZ2VvbV90ZXh0KGxhYmVsID0gcGFzdGUoIm0gPSIsIHNsb3BlX05DLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI7IE1hbnRlbCByID0iLCBtYW50ZWxyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiwgcCA9IiwgcHZhbHVlICksIAogICAgICAgICAgICAgICAgICAgICAgICAgIG1hcHBpbmcgPSBhZXMoeCA9IDgwLCB5ID0gLTAuMDAyKSkKCmxtb2RlbF9wbG90X05DCgojZ2dzYXZlKCJOQ19JQkQucGRmIiwgcGxvdD1jbG93bl9wbG90LGRldmljZT0icGRmIiwgd2lkdGg9NywgaGVpZ2h0PTUsdW5pdHM9ImluIikKCmBgYAoKWW93emEuIE5lZ2F0aXZlIHNsb3BlISBBcyBDZWNpbGUgaGFkIGFscmVhZHkgbWVhc3VyZWQuIEJ1dCB0aGUgRnN0IHZhbHVlcyBhcmUgcmVhbGx5IHRlZW55LgoKIyMjIENhbGN1bGF0ZSBFZmZlY3RpdmUgU2l6ZQoKVGFrZSB0aGUgaGFybW9uaWMgbWVhbiBvZiB0aGUgTmUgYWNyb3NzIGFsbCBwb3BzCgpgYGB7cn0KTmVfZXN0aW1hdGVzX05DIDwtIE5lX2VzdGltYXRlc19mICU+JSBmaWx0ZXIoUG9wdWxhdGlvbiAlaW4lIE5DcG9wcyRBYmJyKQoKI3dyaXRlX2NzdihOYl9lc3RpbWF0ZXNfZiwiTmVFc3RpbWF0b3IvTmJfZXN0aW1hdGVzX3JlY3J1aXRzX05lVGFibGUuY3N2IikKTmVfZXN0aW1hdGVzX05DWyxjKDE6NCw4LDExLDEyKV0KCiMgaGFybW9uaWMgbWVhbiBvZiBOYiwgZm9sbG93aW5nIFdhcGxlcyBhbmQgRG8gMjAxMApOZV9obV9OQyA8LSBoYXJtX21lYW4oTmVfZXN0aW1hdGVzX05DJE5lKQoKYGBgCgojIyMgTmUgdnMuIFNhbXBsaW5nIFdpbmRvdwoKTGV0J3MgY2x1c3RlciB0aGUgc2l0ZXMgYnkgVVBHTUEKYGBge3J9CnBsb3QoaGNsdXN0KGdjZGlzdHNfTkMsImF2ZXJhZ2UiKSkKYGBgCgojIyMjIDEwa20KTGV0J3MgZXhwbG9yZSBOZSBhbmQgRmlzIHdoZW4gbHVtcGluZyBwb3B1bGF0aW9ucy4uLiAgRmlyc3QgbHVtcCBwb3B1bGF0aW9ucyB0aGF0IGFyZSBsZXNzIHRoYW4gMTAga20gYXBhcnQKCmBgYHtyfQpzdGF0cy5OQyRGaXMgJT4lIGFzX3RpYmJsZSgpICU+JSBzdW1tYXJpemUoYWNyb3NzKGV2ZXJ5dGhpbmcoKSxtZWFuLCBuYS5ybT1UUlVFKSkKCkRhcnVhbnVzLk5DLjEwa20gPC0gRGFydWFudXMuTkMKCkRhcnVhbnVzLk5DLjEwa21AcG9wIDwtICBEYXJ1YW51cy5OQy4xMGttQHBvcCAlPiUgZmN0X2NvbGxhcHNlKAogICBjZW50ZXIgPSBjKCJHbyIsIkxhciIpLAogKQoKRGFydWFudXMuTkMuMTBrbS5zdGF0cyA8LSBiYXNpYy5zdGF0cyhEYXJ1YW51cy5OQy4xMGttKQoKRGFydWFudXMuTkMuMTBrbS5zdGF0cyRGaXMgJT4lIGFzX3RpYmJsZSgpICU+JSBzdW1tYXJpemUoYWNyb3NzKGV2ZXJ5dGhpbmcoKSxtZWFuLCBuYS5ybT1UUlVFKSkKCm1lYW5GaXNfTkNfMTBrbSA8LSBEYXJ1YW51cy5OQy4xMGttLnN0YXRzJEZpcyAlPiUgYXNfdGliYmxlKCkgJT4lIHN1bW1hcml6ZShhY3Jvc3MoZXZlcnl0aGluZygpLG1lYW4sIG5hLnJtPVRSVUUpKSAlPiUgCiAgc3VtbWFyaXplKG1lYW5GaXMgPSByb3dNZWFucyguKSkKCiNnZW5pbmRfdG9fZ2VuZXBvcChEYXJ1YW51cy5OQy4xMGttLG91dHB1dCA9ICJEYXJ1YW51cy9OQy9EYXJ1YW51c19OQ18xMGttLnR4dCIpCgpOZV9lc3RpbWF0ZXNfTkMxMGttIDwtIHJlYWRfTmVFc3RpbWF0b3IoCiAgICAgICAgICAgICAgICAgICAgICAgICJOZUVzdGltYXRvci9EYXJ1YW51c19MRE5lX05DXzEwa214TEQudHh0IikKTmVfZXN0aW1hdGVzX05DMTBrbSA8LSBXREZpbHRlcihOZV9lc3RpbWF0ZXNfTkMxMGttLCAxMCkKCgpOZV9obV9OQzEwa20gPC0gaGFybV9tZWFuKE5lX2VzdGltYXRlc19OQzEwa20kTmUpCgpgYGAKCiMjIyMgMjBrbSAKCk5vdyBtb3ZlIHVwIHRvIDIwIGttCgpgYGB7cn0KRGFydWFudXMuTkMuMjBrbSA8LSBEYXJ1YW51cy5OQwoKRGFydWFudXMuTkMuMjBrbUBwb3AgPC0gIERhcnVhbnVzLk5DLjIwa21AcG9wICU+JSBmY3RfY29sbGFwc2UoCiAgIGNlbnRlciA9IGMoIk1CTyIsIkxhciIsIkdvIiwiUUJXIikKICkKCkRhcnVhbnVzLk5DLjIwa20uc3RhdHMgPC0gYmFzaWMuc3RhdHMoRGFydWFudXMuTkMuMjBrbSkKCkRhcnVhbnVzLk5DLjIwa20uc3RhdHMkRmlzICU+JSBhc190aWJibGUoKSAlPiUgc3VtbWFyaXplKGFjcm9zcyhldmVyeXRoaW5nKCksbWVhbiwgbmEucm09VFJVRSkpCm1lYW5GaXNfTkNfMjBrbSA8LSBEYXJ1YW51cy5OQy4yMGttLnN0YXRzJEZpcyAlPiUgYXNfdGliYmxlKCkgJT4lCiAgc3VtbWFyaXplKGFjcm9zcyhldmVyeXRoaW5nKCksbWVhbiwgbmEucm09VFJVRSkpICU+JSBzdW1tYXJpemUobWVhbkZpcyA9IHJvd01lYW5zKC4pKQoKI2dlbmluZF90b19nZW5lcG9wKERhcnVhbnVzLk5DLjIwa20sb3V0cHV0ID0gIk5DL0RhcnVhbnVzX05DXzIwa20udHh0IikKCk5lX2VzdGltYXRlc19OQzIwa20gPC0gcmVhZF9OZUVzdGltYXRvcihmaWxlID0gIk5lRXN0aW1hdG9yL0RhcnVhbnVzX0xETmVfTkNfMjBrbXhMRC50eHQiKQpOZV9lc3RpbWF0ZXNfTkMyMGttIDwtIFdERmlsdGVyKE5lX2VzdGltYXRlc19OQzIwa20sIDEwKQoKTmVfaG1fTkMyMGttIDwtIGhhcm1fbWVhbihOZV9lc3RpbWF0ZXNfTkMyMGttJE5lKQoKCgoKYGBgCgojIyMjIDQwa20gCk5vdyBtb3ZlIHVwIHRvIDQwIGttCmBgYHtyfQpEYXJ1YW51cy5OQy40MGttIDwtIERhcnVhbnVzLk5DCgpEYXJ1YW51cy5OQy40MGttQHBvcCA8LSAgRGFydWFudXMuTkMuNDBrbUBwb3AgJT4lIGZjdF9jb2xsYXBzZSgKICAgbm9ydGggPSBjKCJNYXJhIiwiVGVuIiksCiAgIGNlbnRlciA9IGMoIk1CTyIsIkxhciIsIkdvIiwiUUJXIikKICkKCkRhcnVhbnVzLk5DLjQwa20uc3RhdHMgPC0gYmFzaWMuc3RhdHMoRGFydWFudXMuTkMuNDBrbSkKCkRhcnVhbnVzLk5DLjQwa20uc3RhdHMkRmlzICU+JSBhc190aWJibGUoKSAlPiUgc3VtbWFyaXplKGFjcm9zcyhldmVyeXRoaW5nKCksbWVhbiwgbmEucm09VFJVRSkpCgptZWFuRmlzX05DXzQwa20gPC0gRGFydWFudXMuTkMuNDBrbS5zdGF0cyRGaXMgJT4lIGFzX3RpYmJsZSgpICU+JQogIHN1bW1hcml6ZShhY3Jvc3MoZXZlcnl0aGluZygpLG1lYW4sIG5hLnJtPVRSVUUpKSAlPiUgc3VtbWFyaXplKG1lYW5GaXMgPSByb3dNZWFucyguKSkKCiNnZW5pbmRfdG9fZ2VuZXBvcChEYXJ1YW51cy5OQy40MGttLG91dHB1dCA9ICJOQy9EYXJ1YW51c19OQ180MGttLnR4dCIpCgpOZV9lc3RpbWF0ZXNfTkM0MGttIDwtIHJlYWRfTmVFc3RpbWF0b3IoZmlsZSA9ICJOZUVzdGltYXRvci9EYXJ1YW51c19MRE5lX05DXzQwa214TEQudHh0IikKTmVfZXN0aW1hdGVzX05DNDBrbSA8LSBXREZpbHRlcihOZV9lc3RpbWF0ZXNfTkM0MGttLCAxMCkKCk5lX2htX05DNDBrbSA8LSBoYXJtX21lYW4oTmVfZXN0aW1hdGVzX05DNDBrbSROZSkKCgoKCmBgYAoKIyMjIyAxMDBrbQoKTm93IG1vdmUgdXAgdG8gMTAwIGttCmBgYHtyfQpEYXJ1YW51cy5OQy4xMDBrbSA8LSBEYXJ1YW51cy5OQwoKRGFydWFudXMuTkMuMTAwa21AcG9wIDwtICBEYXJ1YW51cy5OQy4xMDBrbUBwb3AgJT4lIGZjdF9jb2xsYXBzZSgKICBub3J0aCA9IGMoIk1hcmEiKSwKICBlYXN0ID0gYygiTUJPIiwiTGFyIiwiR28iLCJRQlciLCJUb3RlIiwiVGVuIikKICkKCkRhcnVhbnVzLk5DLjEwMGttLnN0YXRzIDwtIGJhc2ljLnN0YXRzKERhcnVhbnVzLk5DLjEwMGttKQoKRGFydWFudXMuTkMuMTAwa20uc3RhdHMkRmlzICU+JSBhc190aWJibGUoKSAlPiUgc3VtbWFyaXplKGFjcm9zcyhldmVyeXRoaW5nKCksbWVhbiwgbmEucm09VFJVRSkpCgptZWFuRmlzX05DXzEwMGttIDwtIERhcnVhbnVzLk5DLjEwMGttLnN0YXRzJEZpcyAlPiUgYXNfdGliYmxlKCkgJT4lCiAgc3VtbWFyaXplKGFjcm9zcyhldmVyeXRoaW5nKCksbWVhbiwgbmEucm09VFJVRSkpICU+JSBzdW1tYXJpemUobWVhbkZpcyA9IHJvd01lYW5zKC4pKQoKCgojZ2VuaW5kX3RvX2dlbmVwb3AoRGFydWFudXMuTkMuMTAwa20sb3V0cHV0ID0gIk5DL0RhcnVhbnVzX05DXzEwMGttLnR4dCIpCgpOZV9lc3RpbWF0ZXNfTkMxMDBrbSA8LSByZWFkX05lRXN0aW1hdG9yKGZpbGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTmVFc3RpbWF0b3IvRGFydWFudXNfTEROZV9OQ18xMDBrbXhMRC50eHQiKQpOZV9lc3RpbWF0ZXNfTkMxMDBrbSA8LSBXREZpbHRlcihOZV9lc3RpbWF0ZXNfTkMxMDBrbSwgMTApCgojcmVwbGFjZSBvbmUgdmVyeSBsYXJnZSBlc3RpbWF0ZSBvZiBOZSB3aXRoIDIwLDAwMDAKTmVfZXN0aW1hdGVzX05DMTAwa20kTmVbMV0gPC0gMjAwMDAKCk5lX2htX05DMTAwa20gPC0gaGFybV9tZWFuKE5lX2VzdGltYXRlc19OQzEwMGttJE5lKQoKCgoKYGBgCgojIyMjIDIwMGttCk5vdyBtb3ZlIHVwIHRvIDIwMCBrbSAoYWxsIHBvcHMgYXMgb25lKQoKYGBge3J9Ck5lX2VzdGltYXRlc19OQzIwMGttIDwtIHJlYWRfTmVFc3RpbWF0b3IoZmlsZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOZUVzdGltYXRvci9EYXJ1YW51c19MRE5lX05DXzFwb3B4TEQudHh0IikKTmVfZXN0aW1hdGVzX05DMjAwa20gPC0gV0RGaWx0ZXIoTmVfZXN0aW1hdGVzX05DMjAwa20sIDEwKQoKCgpOZV9obV9OQzIwMGttIDwtIE5lX2VzdGltYXRlc19OQzIwMGttJE5lCk5lX2FsbF9OQyA8LSBOZV9lc3RpbWF0ZXNfTkMyMDBrbSROZQoKTmVfYWxsX05DX0NJIDwtIGMoTmVfZXN0aW1hdGVzX05DMjAwa20kUGFyYW1ldHJpY0xvdyxOZV9lc3RpbWF0ZXNfTkMyMDBrbSRQYXJhbWV0cmljSGlnaCkKYGBgCgojIyMjIEZpZ3VyZQoKYGBge3J9Ck5Dd2luZG93cyA8LSB0aWJibGUoU2FtcGxlV2luZG93ID0gYygwLDEwLDIwLDQwLDEwMCwyMDApLAogICAgICAgICAgICAgICAgICAgICAgaG1fTmUgPSBjKE5lX2htX05DLE5lX2htX05DMTBrbSxOZV9obV9OQzIwa20sTmVfaG1fTkM0MGttLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5lX2htX05DMTAwa20sTmVfaG1fTkMyMDBrbSkpCgpnZ3Bsb3QoTkN3aW5kb3dzLCBhZXMoeCA9IFNhbXBsZVdpbmRvdywgeSA9IGhtX05lKSkgKyBnZW9tX3BvaW50KCkgKyBnZW9tX2xpbmUoKSArCiAgeWxpbSgwLDIwMDAwKSArIHhsaW0oMCwzMDApCiNnZ3NhdmUoIk5DX05lX3ZfU2FtcERpc3RhbmNlLnBkZiIsaGVpZ2h0ID0gNywgd2lkdGggPSA3KQpgYGAKCgojIyMgQ2FsY3VsYXRlIEVmZmVjdGl2ZSBEZW5zaXR5CgpgYGB7cn0KIyBEaXZpZGUgYnkgbWVhbiBkaXN0YW5jZSBiZXR3ZWVuIHNhbXBsaW5nIHNpdGVzIHRvIGdldCBkZW5zaXR5CkRlX05DIDwtIE5lX2htX05DL21lYW5kaXN0c19OQwpEZV9hbGxfTkMgPC0gTmVfYWxsX05DIC8gbWF4ZGlzdF9OQwpgYGAKCk1lYW4gZGVuc2l0eSBpcyBgciBEZV9OQ2AgaW5kaXZpZHVhbHMva20sIG9yIGlmIHdlIGRvIHRoZSB3aG9sZSBzYW1wbGUgYXMgYSBzaW5nbGUgcG9wdWxhdGlvbiBgciBEZV9hbGxfTkNgIGluZGl2aWR1YWxzL2ttCgojIyBNaWdyYWlOZSBNZXRob2QKCgojIyMgUnVubmluZyBNaWdyYWlOZQoKSSBtb2RpZmllZCB0aGUgZ2VuZXBvcCBmaWxlIGJ5IGFkZGluZyBzYW1wbGluZyBjb29yZGluYXRlcyBhcyB0aGUgbmFtZSBvZiB0aGUgbGFzdCBpbmRpdmlkdWFsIGluIGVhY2ggcG9wdWxhdGlvbi4gVGhlc2UgY29vcmRpbmF0ZXMgd2VyZSBkaXN0YW5jZXMgaW4ga20gYWxvbmcgYSB0aGUgbW9zdGx5IGxpbmVhciBTVyBjb2FzdGxpbmUgb2YgTmV3IENhbGVkb25pYSwgd2hpY2ggcnVucyBhIHRvdGFsIG9mIH42MTJrbS4gSXQgaXMgfjQxOGttIHRvIHRoZSBmaXJzdCBwb3B1bGF0aW9uIGF0IE1hcmEsIHNvIEkgYW0gYWRkaW5nIHRoYXQgdmFsdWUgdG8gdGhlIGNvb3JkaW5hdGVzIGluIHRoZSBmaWxlLgoKYGBge3J9CmRpc3Rmcm9tUDFfTkMrNDE4CmBgYAoKIyMjIyBGaXJzdCBSdW4KCmBgYHtiYXNoIGV2YWwgPSBGfQoKR2VuZXBvcEZpbGVOYW1lPS4uL0RhcnVhbnVzX05DLnR4dApEZW1vZ3JhcGhpY01vZGVsPUxpbmVhcklCRAojIEkgbW9kaWZpZWQgdGhlIGdlbmVwb3AgZmlsZSBieSBhZGRpbmcgc2FtcGxpbmcgY29vcmRpbmF0ZXMgYXMgdGhlIG5hbWUgb2YgdGhlIAojIGxhc3QgaW5kaXZpZHVhbCBpbiBlYWNoIHBvcHVsYXRpb24uIFRoZXNlIGNvb3JkaW5hdGVzIHdlcmUgZGlzdGFuY2VzIGluIGttIGFsb25nIAojIGEgdGhlIG1vc3RseSBsaW5lYXIgU1cgY29hc3RsaW5lIG9mIE5ldyBDYWxlZG9uaWEsIAojIHdoaWNoIHJ1bnMgYSB0b3RhbCBvZiB+NjEya20uIEl0IGlzIH40MThrbSB0byB0aGUgZmlyc3QgcG9wdWxhdGlvbiBhdCBNYXJhLCAKIyBzbyBJIGFtIGFkZGluZyB0aGF0IHZhbHVlIHRvIHRoZSBjb29yZGluYXRlcyBpbiB0aGUgZmlsZS4KUFNPTk1heD02MTIgMAojTmVpZ2hib3Job29kIHNpemUgaXMgYmFzZWQgb24gbWVhbiBkaXN0YW5jZSBiZXR3ZWVuIHBvcHVsYXRpb25zID0gMjUuMDgKIzYxMi8yNS4wOCA9IDI0LjQwIHNvIEkgd2lsbCB1c2UgMjUgYmlucwpHZW9CaW5OYnI9MjUKR2VvVW5pdD0gaW5kLmttCiNhbHRlcm5hdGUgd2F5IG9mIHNwZWNpZnlpbmcgdGhlIGhhYml0YXQsIG5vdCB1c2VkIGZvciBub3cKI2hhYml0YXRQYXJzPSAwLjUgMC41IDQwMCAxIDAKI2hhYml0YXRQYXJzPTAgMCAwIDMwMCAwCiNNdXRhdGlvbiBNb2RlbCBpcyBLLWFsbGVsZSA9IFBJTSwgd2l0aCBrPTIgZm9yIFNOUHMuIEdpdmVuSyBpcyBudW1iZXIgb2YgYWxsZWxlcwojIGF0IGVhY2ggbG9jdXMKTXV0YXRpb25Nb2RlbD1QSU0KR2l2ZW5LPTI2LDM1LDExLDU3LDQ3LDMyLDMwLDIzLDU3LDM0LDQ0CnNhbXBsaW5nU3BhY2U9LCwKc2FtcGxpbmdTY2FsZT0sLAojQW5hbHlzaXMgLSB0aGlzIHdpbGwgZG8gNSBydW5zIG9mIDEwMCBwb2ludHMgYW5kCiNvdmVyd3JpdGUgdGhvc2Ugd2l0aCAxMCBydW5zIG9mIDI1MCBwb2ludHMKd3JpdGVTZXF1ZW5jZT0gT3ZlcixPdmVyLE92ZXIsT3ZlcixPdmVyLEFwcGVuZCwxMApTdGF0aXN0aWNTZXF1ZW5jZT1QQUMKUG9pbnROdW1iZXI9MTAwLDEwMCwxMDAsMTAwLDEwMCwyNTAKTnJ1bnNwZXJwb2ludD0zMCwzMCwzMCwzMCwzMCw1MAojV2lkZSBwcmlvcnMgb24gTmV1LCBOZW0gYW5kIGcKTG93ZXJCb3VuZD0wLjEsMSwwClVwcGVyYm91bmQ9MSwyNTAwLDEKb25lRGltQ0k9IDJObXUsIDJObSwgTmIsIGNvbmRTMgpDb3JlTmJyRm9yUj00CiNQbG90cz0gYWxsMURQcm9maWxlcwoxRFByb2ZpbGVzPTJObXUsIDJObSwgTmIsIGNvbmRTMiwgZwpleHRyYXNjYWxlPU5iPWxvZ3NjYWxlCmdyYXBoaWNGb3JtYXQ9cGRmCiN3cml0ZUFkSG9jRmlsZXM9VApgYGAKCgpBbmQgd293LCB0aGF0IGZpcnN0IHJ1biBjb21wbGV0ZWQgaW4gMjE5IG1pbnV0ZXMgd2l0aCBhIHJlYXNvbmFibGUgcmVzdWx0LCBzbyBJIHRoaW5rIEknbSBqdXN0IGdvaW5nIHRvIHVzZSBpdCBmb3Igbm93LiBJdCBkaWRuJ3QgY2FsY3VsYXRlIG9yIHBsb3QgY29uZFMyIHRob3VnaC4uLgoKIyMjIyBTZWNvbmQgUnVuCgpgYGB7YmFzaCBldmFsID0gRn0KR2VuZXBvcEZpbGVOYW1lPS4uL0RhcnVhbnVzX05DLnR4dApEZW1vZ3JhcGhpY01vZGVsPUxpbmVhcklCRAojIEkgbW9kaWZpZWQgdGhlIGdlbmVwb3AgZmlsZSBieSBhZGRpbmcgc2FtcGxpbmcgY29vcmRpbmF0ZXMgYXMgdGhlIG5hbWUgb2YgdGhlIAojIGxhc3QgaW5kaXZpZHVhbCBpbiBlYWNoIHBvcHVsYXRpb24uIFRoZXNlIGNvb3JkaW5hdGVzIHdlcmUgZGlzdGFuY2VzIGluIGttIGFsb25nIAojIGEgdGhlIG1vc3RseSBsaW5lYXIgU1cgY29hc3RsaW5lIG9mIE5ldyBDYWxlZG9uaWEsIAojIHdoaWNoIHJ1bnMgYSB0b3RhbCBvZiB+NjEya20uIEl0IGlzIH40MThrbSB0byB0aGUgZmlyc3QgcG9wdWxhdGlvbiBhdCBNYXJhLCAKIyBzbyBJIGFtIGFkZGluZyB0aGF0IHZhbHVlIHRvIHRoZSBjb29yZGluYXRlcyBpbiB0aGUgZmlsZS4KUFNPTk1pbj0wIDAKUFNPTk1heD02MTIgMAojTmVpZ2hib3Job29kIHNpemUgaXMgYmFzZWQgb24gbWVhbiBkaXN0YW5jZSBiZXR3ZWVuIHBvcHVsYXRpb25zID0gMjUuMDgKIzYxMi8yNS4wOCA9IDI0LjQwIHNvIEkgd2lsbCB1c2UgMjYgYmlucwpHZW9CaW5OYnI9MjYKR2VvVW5pdD0gaW5kLmttCiNhbHRlcm5hdGUgd2F5IG9mIHNwZWNpZnlpbmcgdGhlIGhhYml0YXQsIG5vdCB1c2VkIGZvciBub3cKI2hhYml0YXRQYXJzPSAwLjUgMC41IDQwMCAxIDAKI2hhYml0YXRQYXJzPTAgMCAwIDMwMCAwCiNNdXRhdGlvbiBNb2RlbCBpcyBLLWFsbGVsZSA9IFBJTSwgd2l0aCBrPTIgZm9yIFNOUHMKTXV0YXRpb25Nb2RlbD1QSU0KR2l2ZW5LPTI2LDM1LDExLDU3LDQ3LDMyLDMwLDIzLDU3LDM0LDQ0CnNhbXBsaW5nU3BhY2U9LCwKc2FtcGxpbmdTY2FsZT0sLAojQW5hbHlzaXMgLSB0aGlzIHdpbGwgZG8gNSBydW5zIG9mIDEwMCBwb2ludHMgYW5kCiNvdmVyd3JpdGUgdGhvc2Ugd2l0aCAxMCBydW5zIG9mIDI1MCBwb2ludHMKd3JpdGVTZXF1ZW5jZT0gT3ZlcixPdmVyLE92ZXIsT3ZlcixPdmVyLEFwcGVuZCwxMApTdGF0aXN0aWNTZXF1ZW5jZT1QQUMKUG9pbnROdW1iZXI9MTAwLDEwMCwxMDAsMTAwLDEwMCwyNTAKTnJ1bnNwZXJwb2ludD0zMCwzMCwzMCwzMCwzMCw1MAojV2lkZSBwcmlvcnMgb24gTmV1LCBOZW0gYW5kIGcKTG93ZXJCb3VuZD0wLjEsMSwwClVwcGVyYm91bmQ9MiwxMDAwMCwxCm9uZURpbUNJPSAyTm11LCAyTm0sIE5iLCBjb25kUzIKQ29yZU5ickZvclI9NAojUGxvdHM9IGFsbDFEUHJvZmlsZXMKMURQcm9maWxlcz0yTm11LCAyTm0sIE5iLCBjb25kUzIsIGcKZXh0cmFzY2FsZT1OYj1sb2dzY2FsZQpncmFwaGljRm9ybWF0PXBkZgojd3JpdGVBZEhvY0ZpbGVzPVQKYGBgCgpUaGlzIGZpbmlzaGVkIGluIDI1MCBtaW51dGVzLCBhbmQgaGFkIHZlcnkgc2ltaWxhciByZXN1bHRzIHRvIHRoZSBmaXJzdCBydW4KCiMjIyMgVGhpcmQgUnVuCgpBZnRlciByZW1vdmluZyAzIGxvY2kKCmBgYHtiYXNoIGV2YWwgPSBGfQpHZW5lcG9wRmlsZU5hbWU9Li4vLi4vRGFydWFudXNfTkMudHh0CkRlbW9ncmFwaGljTW9kZWw9TGluZWFySUJECiMgSSBtb2RpZmllZCB0aGUgZ2VuZXBvcCBmaWxlIGJ5IGFkZGluZyBzYW1wbGluZyBjb29yZGluYXRlcyBhcyB0aGUgbmFtZSBvZiB0aGUgCiMgbGFzdCBpbmRpdmlkdWFsIGluIGVhY2ggcG9wdWxhdGlvbi4gVGhlc2UgY29vcmRpbmF0ZXMgd2VyZSBkaXN0YW5jZXMgaW4ga20gYWxvbmcgCiMgYSB0aGUgbW9zdGx5IGxpbmVhciBTVyBjb2FzdGxpbmUgb2YgTmV3IENhbGVkb25pYSwgCiMgd2hpY2ggcnVucyBhIHRvdGFsIG9mIH42MTJrbS4gSXQgaXMgfjQxOGttIHRvIHRoZSBmaXJzdCBwb3B1bGF0aW9uIGF0IE1hcmEsIAojIHNvIEkgYW0gYWRkaW5nIHRoYXQgdmFsdWUgdG8gdGhlIGNvb3JkaW5hdGVzIGluIHRoZSBmaWxlLgpQU09OTWluPTAgMApQU09OTWF4PTYxMiAwCiNOZWlnaGJvcmhvb2Qgc2l6ZSBpcyBiYXNlZCBvbiBtZWFuIGRpc3RhbmNlIGJldHdlZW4gcG9wdWxhdGlvbnMgPSAyNS4wOAojNjEyLzI1LjA4ID0gMjQuNDAgc28gSSB3aWxsIHVzZSAyNSBiaW5zCkdlb0Jpbk5icj0yNQpHZW9Vbml0PSBpbmQua20KI2FsdGVybmF0ZSB3YXkgb2Ygc3BlY2lmeWluZyB0aGUgaGFiaXRhdCwgbm90IHVzZWQgZm9yIG5vdwojaGFiaXRhdFBhcnM9IDAuNSAwLjUgNDAwIDEgMAojaGFiaXRhdFBhcnM9MCAwIDAgMzAwIDAKI011dGF0aW9uIE1vZGVsIGlzIEstYWxsZWxlID0gUElNLCB3aXRoIGs9MiBmb3IgU05QcwpNdXRhdGlvbk1vZGVsPVBJTQpHaXZlbks9MjYsMTEsNTcsMzIsMzAsMjMsNTcsNDQKc2FtcGxpbmdTcGFjZT0sLApzYW1wbGluZ1NjYWxlPSwsCiNBbmFseXNpcyAtIHRoaXMgd2lsbCBkbyA1IHJ1bnMgb2YgMTAwIHBvaW50cyBhbmQKI292ZXJ3cml0ZSB0aG9zZSB3aXRoIDEwIHJ1bnMgb2YgMjUwIHBvaW50cwp3cml0ZVNlcXVlbmNlPSBPdmVyLE92ZXIsT3ZlcixPdmVyLE92ZXIsQXBwZW5kLDEwClN0YXRpc3RpY1NlcXVlbmNlPVBBQwpQb2ludE51bWJlcj0xMDAsMTAwLDEwMCwxMDAsMTAwLDI1MApOcnVuc3BlcnBvaW50PTMwLDMwLDMwLDMwLDMwLDUwCiNXaWRlIHByaW9ycyBvbiBOZXUsIE5lbSBhbmQgZwpMb3dlckJvdW5kPTAuMSwxLDAKVXBwZXJib3VuZD0yLDEwMDAwLDEKb25lRGltQ0k9IDJObXUsIDJObSwgTmIsIGNvbmRTMgpDb3JlTmJyRm9yUj00ClBsb3RzPSBhbGwxRFByb2ZpbGVzCiMxRFByb2ZpbGVzPTJObXUsIDJObSwgTmIsIGNvbmRTMiwgZwpleHRyYXNjYWxlPU5iPWxvZ3NjYWxlCmdyYXBoaWNGb3JtYXQ9cGRmCiN3cml0ZUFkSG9jRmlsZXM9VApgYGAKCiMjIyMgRm91cnRoIFJ1bgoKQW5kLCBsbywgSSBmb3Jnb3QgdG8gdXNlIHRoZSBjb25kUzIgcGFyYW1ldGVyaXphdGlvbiB0aGF0IGlzIHJlY29tbWVuZGVkIGZvciB3ZWFrIElCRCBzaWduYWxzIGJ5IEBsZWJsb2lzTWlncmFpTmVNYW51YWwyMDIwISAKCmBgYHtiYXNoIGV2YWwgPSBGfQpHZW5lcG9wRmlsZU5hbWU9Li4vLi4vRGFydWFudXNfTkMudHh0CkRlbW9ncmFwaGljTW9kZWw9TGluZWFySUJECiMgSSBtb2RpZmllZCB0aGUgZ2VuZXBvcCBmaWxlIGJ5IGFkZGluZyBzYW1wbGluZyBjb29yZGluYXRlcyBhcyB0aGUgbmFtZSBvZiB0aGUgCiMgbGFzdCBpbmRpdmlkdWFsIGluIGVhY2ggcG9wdWxhdGlvbi4gVGhlc2UgY29vcmRpbmF0ZXMgd2VyZSBkaXN0YW5jZXMgaW4ga20gYWxvbmcgCiMgYSB0aGUgbW9zdGx5IGxpbmVhciBTVyBjb2FzdGxpbmUgb2YgTmV3IENhbGVkb25pYSwgCiMgd2hpY2ggcnVucyBhIHRvdGFsIG9mIH42MTJrbS4gSXQgaXMgfjQxOGttIHRvIHRoZSBmaXJzdCBwb3B1bGF0aW9uIGF0IE1hcmEsIAojIHNvIEkgYW0gYWRkaW5nIHRoYXQgdmFsdWUgdG8gdGhlIGNvb3JkaW5hdGVzIGluIHRoZSBmaWxlLgpQU09OTWluPTAgMApQU09OTWF4PTYxMiAwCiNOZWlnaGJvcmhvb2Qgc2l6ZSBpcyBiYXNlZCBvbiBtZWFuIGRpc3RhbmNlIGJldHdlZW4gcG9wdWxhdGlvbnMgPSAyNS4wOAojNjEyLzI1LjA4ID0gMjQuNDAgc28gSSB3aWxsIHVzZSAyNSBiaW5zCkdlb0Jpbk5icj0yNQpHZW9Vbml0PSBpbmQua20KI2FsdGVybmF0ZSB3YXkgb2Ygc3BlY2lmeWluZyB0aGUgaGFiaXRhdCwgbm90IHVzZWQgZm9yIG5vdwojaGFiaXRhdFBhcnM9IDAuNSAwLjUgNDAwIDEgMAojaGFiaXRhdFBhcnM9MCAwIDAgMzAwIDAKI011dGF0aW9uIE1vZGVsIGlzIEstYWxsZWxlID0gUElNLCB3aXRoIGs9MiBmb3IgU05QcwpNdXRhdGlvbk1vZGVsPVBJTQpHaXZlbks9MjYsMTEsNTcsMzIsMzAsMjMsNTcsNDQKI3NhbXBsaW5nIC0gdGhpcyBwZXJmb3JtcyB1bmlmb3JtIHNhbXBsaW5nIG9mIGxuKHNpZ21hXjIpLCB3aGljaCBpcyB0aGUgcXVhbnRpdHkgd2UgYXJlIGludGVyZXN0ZWQgaW4Kc2FtcGxpbmdTcGFjZT0sLGNvbmRTMgpzYW1wbGluZ1NjYWxlPSwsbG9nc2NhbGUKI0FuYWx5c2lzIC0gdGhpcyB3aWxsIGRvIDUgcnVucyBvZiAxMDAgcG9pbnRzIGFuZAojb3ZlcndyaXRlIHRob3NlIHdpdGggMTAgcnVucyBvZiAyNTAgcG9pbnRzCndyaXRlU2VxdWVuY2U9IE92ZXIsT3ZlcixPdmVyLE92ZXIsT3ZlcixBcHBlbmQsMTAKU3RhdGlzdGljU2VxdWVuY2U9UEFDClBvaW50TnVtYmVyPTEwMCwxMDAsMTAwLDEwMCwxMDAsMjUwCk5ydW5zcGVycG9pbnQ9MzAsMzAsMzAsMzAsMzAsNTAKI1dpZGUgcHJpb3JzIG9uIE5ldSwgTmVtIGFuZCBnCkxvd2VyQm91bmQ9MC4xLDEsMQpVcHBlcmJvdW5kPTIsMTAwMDAsMTAwMDAwCm9uZURpbUNJPSAyTm11LCAyTm0sIE5iLCBjb25kUzIKQ29yZU5ickZvclI9NApQbG90cz0gYWxsMURQcm9maWxlcwojMURQcm9maWxlcz0yTm11LCAyTm0sIE5iLCBjb25kUzIsIGcKZXh0cmFzY2FsZT1OYj1sb2dzY2FsZQpncmFwaGljRm9ybWF0PXBkZgojd3JpdGVBZEhvY0ZpbGVzPVQKCmBgYAoKRmluaXNoaW5nIGluIGByIDEwMjk2LzYwYCBtaW51dGVzCgojIyMjIFNldmVudGggUnVuCgpCcm91Z2h0IGluIHRoZSBwcmlvcnMgYSBsaXR0bGUuIERpZG4ndCBjaGFuZ2UgdGhlIHJlc3VsdHMgbXVjaC4KCmBgYHtiYXNoIGV2YWw9Rn0KR2VuZXBvcEZpbGVOYW1lPS4uLy4uL0RhcnVhbnVzX05DLnR4dApEZW1vZ3JhcGhpY01vZGVsPUxpbmVhcklCRAojIEkgbW9kaWZpZWQgdGhlIGdlbmVwb3AgZmlsZSBieSBhZGRpbmcgc2FtcGxpbmcgY29vcmRpbmF0ZXMgYXMgdGhlIG5hbWUgb2YgdGhlIAojIGxhc3QgaW5kaXZpZHVhbCBpbiBlYWNoIHBvcHVsYXRpb24uIFRoZXNlIGNvb3JkaW5hdGVzIHdlcmUgZGlzdGFuY2VzIGluIGttIGFsb25nIAojIGEgdGhlIG1vc3RseSBsaW5lYXIgU1cgY29hc3RsaW5lIG9mIE5ldyBDYWxlZG9uaWEsIAojIHdoaWNoIHJ1bnMgYSB0b3RhbCBvZiB+NjEya20uIEl0IGlzIH40MThrbSB0byB0aGUgZmlyc3QgcG9wdWxhdGlvbiBhdCBNYXJhLCAKIyBzbyBJIGFtIGFkZGluZyB0aGF0IHZhbHVlIHRvIHRoZSBjb29yZGluYXRlcyBpbiB0aGUgZmlsZS4KUFNPTk1pbj0wIDAKUFNPTk1heD02MTIgMAojTmVpZ2hib3Job29kIHNpemUgaXMgYmFzZWQgb24gbWVhbiBkaXN0YW5jZSBiZXR3ZWVuIHBvcHVsYXRpb25zID0gMjUuMDgKIzYxMi8yNS4wOCA9IDI0LjQwIHNvIEkgd2lsbCB1c2UgMjYgYmlucwpHZW9CaW5OYnI9MjYKR2VvVW5pdD0gaW5kLmttCiNhbHRlcm5hdGUgd2F5IG9mIHNwZWNpZnlpbmcgdGhlIGhhYml0YXQsIG5vdCB1c2VkIGZvciBub3cKI2hhYml0YXRQYXJzPSAwLjUgMC41IDQwMCAxIDAKI2hhYml0YXRQYXJzPTAgMCAwIDMwMCAwCiNNdXRhdGlvbiBNb2RlbCBpcyBLLWFsbGVsZSA9IFBJTSwgd2l0aCBrPTIgZm9yIFNOUHMKTXV0YXRpb25Nb2RlbD1QSU0KR2l2ZW5LPTI2LDExLDU3LDMyLDMwLDIzLDU3LDQ0CiNzYW1wbGluZyAtIHRoaXMgcGVyZm9ybXMgdW5pZm9ybSBzYW1wbGluZyBvZiBsbihzaWdtYV4yKQpzYW1wbGluZ1NwYWNlPSwsY29uZFMyCnNhbXBsaW5nU2NhbGU9LCxsb2dzY2FsZQojQW5hbHlzaXMgLSB0aGlzIHdpbGwgZG8gNSBydW5zIG9mIDEwMCBwb2ludHMgYW5kCiNvdmVyd3JpdGUgdGhvc2Ugd2l0aCAxMCBydW5zIG9mIDI1MCBwb2ludHMKd3JpdGVTZXF1ZW5jZT0gT3ZlcixPdmVyLE92ZXIsT3ZlcixPdmVyLEFwcGVuZCwxMApTdGF0aXN0aWNTZXF1ZW5jZT1QQUMKUG9pbnROdW1iZXI9MTAwLDEwMCwxMDAsMTAwLDEwMCwyNTAKTnJ1bnNwZXJwb2ludD0zMCwzMCwzMCwzMCwzMCw1MAojV2lkZSBwcmlvcnMgb24gTmV1LCBOZW0gYW5kIGNvbmRzMgpMb3dlckJvdW5kPTAuMSwxLDEKVXBwZXJib3VuZD0yLDYwMDAsMTAwMDAKb25lRGltQ0k9IDJObXUsIDJObSwgTmIsIGNvbmRTMiwgZwojb25lRGltQ0k9IEFsbApDb3JlTmJyRm9yUj00ClBsb3RzPSBhbGwxRFByb2ZpbGVzCiMxRFByb2ZpbGVzPTJObXUsIDJObSwgTmIsIGNvbmRTMiwgZwpleHRyYXNjYWxlPU5iPWxvZ3NjYWxlCmdyYXBoaWNGb3JtYXQ9cGRmCndyaXRlQWRIb2NGaWxlcz1UCmBgYApGaW5pc2hlZCBpbiBgciAxMTI1My82MGAgbWludXRlcy4KCiMjIyBDcmVhdGUgRGlzcGVyc2FsIEtlcm5lbHMKCiMjIyMgU2lnbWEgZXN0aW1hdGVzCgpTbyB3ZSBoYXZlIHR3byByb3V0ZXMgdG8gZXN0aW1hdGUgJFxzaWdtYSQgaGVyZS4gCgojIyMjIEZyb20gTmVpZ2hib3Job29kIFNpemUKCiQkClxzaWdtYSA9IFxzcXJ0XGZyYWN7TlN9ezREX2V9CiQkCgpVc2luZyB0aGUgZXN0aW1hdGUgb2YgbmVpZ2hib3Job29kIHNpemUgYW5kIHRoZSBhYm92ZSBkZXJpdmVkIGVzdGltYXRlIG9mICREX2UkLCAkXHNpZ21hJCBpcyBgciBzaWduaWYoc2lnbWFfZnJvbU5TX05DLDMpYGttLiAKCiMjIyMgRnJvbSBTaWdtYV4yCkFmdGVyIGNvbnZlcnRpbmcgaXQgZnJvbSBsYXR0aWNlIHVuaXRzIHRvIGttCgokJApcc2lnbWEgPSBcc3FydHtcc2lnbWFeMn0KJCQKCgpUaGlzIGdvdCBtZSB0aGUgZm9sbG93aW5nIGVzdGltYXRlcy4KCk91dHB1dCBmcm9tIHJ1biA3LgoKYGBge3IgbWlncmFpbmVfcGFyYW1ldGVyc19ydW4yfQpydW5EaXIgPC0gIi9Vc2Vycy9lcmljL2dpdGh1Yi9JQkRfS2VybmVscy9EYXJ1YW51cy9OQy9NaWdyYWluZS9ydW43IgojcnVuRGlyIDwtICIvVXNlcnMvZWRjNTI0MC9naXRodWIvSUJEX0tlcm5lbHMvRGFydWFudXMvTkMvTWlncmFpbmUvcnVuNyIKcmVzdWx0IDwtIHJlYWRfbWlncmFpbmUocnVuRGlyKQpOU19OQyA8LSByZXN1bHRbIk5TIl0KTlNDSV9OQyA8LSBjKHJlc3VsdFsiTlNDSTEiXSxyZXN1bHRbIk5TQ0kyIl0pCk5tdV9OQyA8LSByZXN1bHRbIk5tdSJdCk5tX05DIDwtIHJlc3VsdFsiTm0iXQpnX05DIDwtIHJlc3VsdFsiZyJdCmxhdHRpY2UyZ2VvZ19OQyA8LSByZXN1bHRbImxhdHRpY2UyZ2VvZyJdCgpzaWdtYTJfTkMgPC0gZ190b19zaWdtYTIoZ19OQykKc2lnbWFfZnJvbXNpZ21hMl9OQyA8LSBzcXJ0KHNpZ21hMl9OQypsYXR0aWNlMmdlb2dfTkMpCnNpZ21hX2Zyb21OU19OQyA8LSBzcXJ0KE5TX05DLyg0KkRlX05DKSkKc2lnbWFDSV9mcm9tTlNfTkMgPC0gc3FydChOU0NJX05DLyg0KkRlX05DKSkKCnNpZ21hX2Zyb21OU19hbGxfTkMgPC0gc3FydChOU19OQy8oNCpEZV9hbGxfTkMpKQpzaWdtYUNJX2Zyb21OU19hbGxfTkMgPC0gc3FydChOU0NJX05DLyg0KkRlX2FsbF9OQykpCgpgYGAKClRoZSAkXHNpZ21hJCB3ZSBnZXQgIGZyb20gTmVpZ2hib3Job29kIFNpemUgJFxzaWdtYSQgaXMgYHIgc2lnbWFfZnJvbU5TX05DYC4gV2UgZ2V0IGEgbXVjaCBsb3dlciBlc3RpbWF0ZSBmcm9tICRcc2lnbWFeMiQsIHdpdGggJFxzaWdtYSQgPSBgciBzaWdtYV9mcm9tc2lnbWEyX05DYAoKIyMjIENvbmZpZGVuY2UgSW50ZXJ2YWxzCgpQcm9wYWdhdGluZyBlcnJvciBzb3J0YSBmb2xsb3dpbmcgUGluc2t5IGV0IGFsLiB0YWJsZSBTMgoKIyMjIyBFcnJvciBpbiBFZmZlY3RpdmUgU2l6ZQoKRm9sbG93aW5nIEBwaW5za3lVc2luZ0lzb2xhdGlvbkRpc3RhbmNlMjAxMCBJIGFtIGdvaW5nIHRvIGJvb3RzdHJhcCBhY3Jvc3MgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGZvciBlYWNoIE5iIGVzdGltYXRlLiBVbmZvcnR1bmF0ZWx5LCB0aGUgbmV3IGphY2trbmlmZSBtZXRob2Qgb2YgQGpvbmVzSW1wcm92ZWRDb25maWRlbmNlSW50ZXJ2YWxzMjAxNiBvZnRlbiByZXN1bHRzIGluIGluZmluaXRlIHVwcGVyIGJvdW5kcyB3aXRoIG1hcmluZSBkYXRhIChidXQgdGhlbiwgc28gZG9lcyB0aGUgcGFyYW1ldHJpYyBtZXRob2QpLiBJJ20gYWxzbyBnb2luZyB0byB1c2UgYSB1bmlmb3JtIGRpc3RyaWJ1dGlvbiBmb3IgdGhlIGVycm9yIGJlY2F1c2UgYXBwcm94aW1hdGluZyB0aGUgZXJyb3Igc3RydWN0dXJlIHdpdGggQ2hpU3Egb3IgTm9ybWFsIGRpc3RyaWJ1dGlvbnMgaXMgbm90IGEgc2ltcGxlIHRhc2sgYW5kIEknbSBqdXN0IHRyeWluZyB0byBnZXQgYSBza2V0Y2ggb2YgdGhlIGVycm9yIHRvIGNvbXBhcmUgd2l0aCBNaWdyYWlOZSBhbnl3YXkuIEknbSBnb2luZyB0byBzZXQgIkluZmluaXRlIiB2YWx1ZXMgaW4gdGhlIHVwcGVyIENJIHRvIDIwLDAwMCBzaW5jZSBJIHJhcmVseSBzZWUgdXBwZXIgYm91bmRzIHRoYXQgaGlnaC4KCiMjIyMjIEZvciBIYXJtb25pYyBNZWFuIE1ldGhvZAoKYGBge3IgTmJfQ0l9Ck5lX2VzdGltYXRlc19OQyRKYWNra25pZmVIaWdoW3doaWNoKGlzLm5hKE5lX2VzdGltYXRlc19OQyRKYWNra25pZmVIaWdoKSldIDwtIDIwMDAwCk5lX2VzdGltYXRlc19OQyRKYWNra25pZmVIaWdoIDwtIGFzLm51bWVyaWMoTmVfZXN0aW1hdGVzX05DJEphY2trbmlmZUhpZ2gpCk5lX2VzdGltYXRlc19OQyRKYWNra25pZmVMb3cgPC0gYXMubnVtZXJpYyhOZV9lc3RpbWF0ZXNfTkMkSmFja2tuaWZlTG93KQoKIyBjb3VsZG4ndCBnZXQgcHVycnI6bWFwIHRvIGRvIHRoaXMsIHNvIHJlc29ydGVkIHRvIG1hcHBseSB0byBzZXQgdXBwZXIgYW5kIGxvd2VyIGJvdW5kcwpOZV9lcnJvcl9OQyA8LSBOVUxMCmZvcihuIGluIDE6MTAwMDAwKXsKICBobSA8LSBoYXJtX21lYW4obWFwcGx5KHJ1bmlmLCBuPTEsIAogICAgICAgICAgICAgICAgICAgbWluPU5lX2VzdGltYXRlc19OQyRKYWNra25pZmVMb3csCiAgICAgICAgICAgICAgICAgICBtYXg9TmVfZXN0aW1hdGVzX05DJEphY2trbmlmZUhpZ2gpKQogIE5lX2Vycm9yX05DIDwtIGMoTmVfZXJyb3JfTkMsaG0pCn0KbmFtZXMoTmVfZXJyb3JfTkMpPC1OVUxMCgpnZ3Bsb3QoZGF0YSA9IHRpYmJsZShOZV9lcnJvcl9OQyksIGFlcyh4PU5lX2Vycm9yX05DKSkgKyBnZW9tX2RlbnNpdHkoKQpgYGAKIyMjIyMgRm9yIFdob2xlIFNhbXBsZSBNZXRob2QKCk5hYXlrZW5zIGFuZCBEJ0Fsb2lhIHNob3dlZCB0aGF0IHVzaW5nIHRoZSB3aG9sZSBzYW1wbGUgdG8gZXN0aW1hdGUgZGVuc2l0eSBnaXZlcyBwcmV0dHkgc2ltaWxhciByZXN1bHRzIHRvIHRoZSBoYXJtb25pYyBtZWFuIG1ldGhvZCwgc28gSSdtIGFsc28gZ29pbmcgdG8gdHJ5IHRoYXQuIAoKYGBge3J9Ck5ibDk1IDwtIE5lX2FsbF9OQ19DSVsxXQpOYnU5NSA8LSBOZV9hbGxfTkNfQ0lbMl0KTmIgPC0gTmVfYWxsX05DCnIyX05DIDwtIE5lX2VzdGltYXRlc19OQzIwMGttJHIyCmVyMl9OQyA8LSAxL05lX2VzdGltYXRlc19OQzIwMGttJFNhbXBTaXplICsgMy4xOS9OZV9lc3RpbWF0ZXNfTkMyMDBrbSRTYW1wU2l6ZSBeMiAjZnJvbSBXYXBsZXMgMjAwNiB0YWJsZSAyCmRmX05DIDwtIE5lX2VzdGltYXRlc19OQzIwMGttJEluZEFsbGVsZXMKI2VmZkRGIGlzIHRoZSBkZWdyZWVzIG9mIGZyZWVkb20gdG8gZ2V0IHRoZSBqYWNra25pZmUgQ0khCiMgVGhpcyBtZXRob2Qgb2YgZmluZGluZyBERiBtYWtlcyBubyBzZW5zZS4gTm90IHN1cmUgaG93IE1hbGluIGdvdCB0aGlzIHRvIHdvcmsKIyBhMiA9IDEwMDAwMAojIGExID0gMTAwCiMgd2hpbGUoYWJzKG1lYW4oYXMubnVtZXJpYyhhMSkpLWEyKSA+IDEpeyAKIyAgIGlmKG1lYW4oYXMubnVtZXJpYyhhMSkpID4gYTIpIGEyID0gYTIgLSAxCiMgICBpZihtZWFuKGFzLm51bWVyaWMoYTEpKSA8IGEyKSBhMiA9IGEyICsgMQojICAgYTEgPSBjKE5ibDk1LCBOYnU5NSkqcWNoaXNxKGMoMC45NzUsIDAuMDI1KSwgZGY9YTIpL05iCiMgfQojIGEyICNkZgoKV2FwbGVzTW9ub05lKHIycChyMl9OQyxlcjJfTkMpKQoKIyB0aGlzIHNob3dzIHRoYXQgd2UgY2FuIGdldCBhcHByb3hpbWF0ZWx5IHdoYXQgTmVFc3RpbWF0b3IgZ2l2ZXMgdXMuLi4gbm90IHN1cmUgd2h5IGl0cyBub3QgZXhhY3QuLi4gbXVzdCBiZSBtaXNzaW5nIHNvbWUgY29ycmVjdGlvbgpyQ0lfTkMgPC0gZGZfTkMqcjJfTkMgLyAocWNoaXNxKGMoMC4wMjUsMC45NzUpLCBkZiA9IGRmX05DKSkKV2FwbGVzTW9ub05lKHJDSV9OQyAtIGVyMl9OQykKCiNhbmQgbm93IHRvIGdldCBhbmQgcGxvdCB0aGUgZXJyb3IgZGlzdHJpYnV0aW9uCk5lX2Vycm9yX2FsbF9OQyA8LSBXYXBsZXNNb25vTmUoKChkZl9OQypyMl9OQykvKHJjaGlzcSgxMDAwMCwgZGYgPSBkZl9OQykpKSAtIGVyMl9OQykKCmdncGxvdChkYXRhID0gdGliYmxlKE5lX2Vycm9yX2FsbF9OQyksIGFlcyh4PU5lX2Vycm9yX2FsbF9OQykpICsgZ2VvbV9kZW5zaXR5KCkgKyB4bGltKDAsMjAwMDApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCmBgYAoKIyMjIyBFcnJvciBpbiBFZmZlY3RpdmUgRGVuc2l0eQoKT25lIGlzc3VlIHdpdGggdGhpcyBhbmFseXNpcyBpcyB0aGF0LCB3aGlsZSBAbmVlbEVzdGltYXRpb25FZmZlY3RpdmVQb3B1bGF0aW9uMjAxMyBtYWtlIGEgZ29vZCBjYXNlIHRoYXQgd2UgYXJlIGVzdGltYXRpbmcgdGhlIE5lIG9mIHRoZSBsb2NhbCBuZWlnaGJvcmhvb2QsIHdlIGRvbid0IGFjdHVhbGx5IGtub3cgd2hhdCB0aGUgc2l6ZSBvZiB0aGUgbmVpZ2hib3Job29kIGlzLiBJbmRlZWQsIHRoYXQncyBhY3R1YWxseSB3aGF0IHdlIGFyZSB0cnlpbmcgdG8gZXN0aW1hdGUuIFtAcGluc2t5VXNpbmdJc29sYXRpb25EaXN0YW5jZTIwMTBdIHVzZWQgbmVpZ2hib3Job29kcyB0aGF0IHdlcmUgMS8yIHRoZSBkaXN0YW5jZSB0byB0aGUgbmV4dCBuZWlnaGJvcmhvb2Qgb24gZWl0aGVyIHNpZGUgb2YgdGhlIHNhbXBsaW5nIHNpdGUsIHdoaWxlIFtAcGluc2t5TWFyaW5lRGlzcGVyc2FsU2NhbGVzMjAxN10gZGlkbid0IGV2ZW4gYXR0ZW1wdCB0aGlzIGFuZCBqdXN0IHVzZWQgdGhlIE5lIG9mIHRoZSB3aG9sZSBzYW1wbGVkIHBvcHVsYXRpb24sIGFuZCBkaXZpZGVkIGJ5IHRoZSBsZW5ndGggb2YgdGhlIHdob2xlIHNhbXBsZWQgYXJlYS4KClRoaXMgaXMgYW5vdGhlciBhcmVhIG9mIHVuY2VydGFpbnR5LCBzbyB3ZSBzaG91bGQgbW9kZWwgdGhlIHVuY2VydGFpbnR5IGluIG5laWdoYm9yaG9vZCBsZW5ndGguIFdlIGtub3cgaXRzIGJldHdlZW4gMTAgYW5kIDQwIGttIGJhc2VkIG9uIHRoZSBOZSB2cy4gU2FtcGxpbmcgV2luZG93IGFuYWx5c2lzIGFib3ZlLi4uCgpgYGB7cn0KCkRlX2Vycm9yX05DIDwtIE5lX2Vycm9yX05DLyBybm9ybSgxMDAwMDAsbWVhbj1tZWFuZGlzdHNfTkMsc2QgPSAxNS8xLjk2KQoKRGVfZXJyb3JfYWxsX05DIDwtIE5lX2Vycm9yX2FsbF9OQyAvIG1heGRpc3RfTkMKCmdncGxvdChkYXRhID0gdGliYmxlKERlX2Vycm9yX2FsbF9OQyksIGFlcyh4PURlX2Vycm9yX2FsbF9OQykpICsgZ2VvbV9kZW5zaXR5KCkgKyB4bGltKDAsMjUwKQoKZ2dwbG90KGRhdGEgPSB0aWJibGUoRGVfZXJyb3JfTkMpLCBhZXMoeD1EZV9lcnJvcl9OQykpICsgZ2VvbV9kZW5zaXR5KCkgKyB4bGltKDAsMjUwKQoKCmBgYAoKIyMjIyBFcnJvciBpbiBOZWlnaGJvcmhvb2QgU2l6ZQoKVXNpbmcgYSB1bmlmb3JtIGRpc3RyaWJ1dGlvbiBpcyBvdXQgYmVjYXVzZSB0aGVyZSBpcyBjbGVhcmx5IGEgcGVha2VkIGRpc3RyaWJ1dGlvbiBpbiB0aGUgTWlncmFpbmUgb3V0cHV0LiBTbyBJIGFtIHVzaW5nIGEgcXVpY2sgZml0IHRvIGEgdHJ1bmNhdGVkIGxvZ25vcm1hbCBkaXN0cmlidXRpb24uCgohW01pZ3JhaW5lX1J1bjJfTmVpZ2hib3Job29kX1RoZXRhXShmaWd1cmVzL0RhX05DX05laWdoYm9yaG9vZC5qcGcpCgpgYGB7ciBOZXcgTmVpZ2hib3Job29kIFNpemUgRXJyb3IgfQpOU0NJX05DCmN1cnZlKGRsbm9ybSh4LCBtZWFubG9nID0gbG9nKE5TX05DKSwgc2Rsb2cgPSBsb2coMi43NWU1KSkpCnFsbm9ybShjKDAuMDI1LDAuOTc1KSxtZWFubG9nID0gbG9nKE5TX05DKSwgc2Rsb2cgPSBsb2coMi43NWU1KSkKYGBgCgoKYGBge3J9CgpOZWlnaGJvcmhvb2RfZXJyb3JfTkMgPC0gcmxub3JtVHJ1bmMobiA9IDEwMDAwMCwgbWVhbmxvZyA9IGxvZyhOU19OQyksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Rsb2cgPSBsb2coMi43NWU1KSwgbWluID0gTlNDSV9OQ1sxXSwgbWF4ID0gTlNDSV9OQ1syXSkKCmdncGxvdChkYXRhID0gdGliYmxlKE5laWdoYm9yaG9vZF9lcnJvcl9OQyksIGFlcyh4PU5laWdoYm9yaG9vZF9lcnJvcl9OQykpICsgCiAgZ2VvbV9kZW5zaXR5KCkgKyBzY2FsZV94X2xvZzEwKCkKCnNpZ21hX2Vycm9yX2Zyb21OU19OQyA8LSBzcXJ0KE5laWdoYm9yaG9vZF9lcnJvcl9OQy8oNCpEZV9lcnJvcl9OQykpCm5hbWVzKHNpZ21hX2Vycm9yX2Zyb21OU19OQykgPC0gTlVMTAoKc2lnbWFfZXJyb3JfZnJvbU5TX2FsbF9OQyA8LSBzcXJ0KE5laWdoYm9yaG9vZF9lcnJvcl9OQy8oNCpEZV9lcnJvcl9hbGxfTkMpKQpuYW1lcyhzaWdtYV9lcnJvcl9mcm9tTlNfYWxsX05DKSA8LSBOVUxMCgpnZ3Bsb3QoZGF0YSA9IHRpYmJsZShzaWdtYV9lcnJvcl9mcm9tTlNfTkMpLCAKICAgICAgIGFlcyh4PXNpZ21hX2Vycm9yX2Zyb21OU19OQykpICsKICBnZW9tX2RlbnNpdHkoKSArIHNjYWxlX3hfbG9nMTAoKQoKZ2dwbG90KGRhdGEgPSB0aWJibGUoc2lnbWFfZXJyb3JfZnJvbU5TX2FsbF9OQyksIAogICAgICAgYWVzKHg9c2lnbWFfZXJyb3JfZnJvbU5TX2FsbF9OQykpICsKICBnZW9tX2RlbnNpdHkoKSArIHNjYWxlX3hfbG9nMTAoKQoKcXVhbnRpbGUoc2lnbWFfZXJyb3JfZnJvbU5TX05DLCBjKDAuMDI1LCAwLjk3NSkpCgpgYGAKCiMjIyMgUGxvdCBEaXNwZXJzYWwgS2VybmVscyAKCgpgYGB7cn0KCmtlcm5lbHBsb3RfTkMgPC0gZ2dwbG90KGRhdGEuZnJhbWUoeD1jKDAsNTAwKSksYWVzKHgpKSArIAogIG1hcCgueCA9IHNhbXBsZShzaWdtYV9lcnJvcl9mcm9tTlNfTkMsMTAwMCksIC5mID0gZnVuY3Rpb24oc2lnbWEpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0X2Z1bmN0aW9uKGZ1biA9IGRleHAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3MgPSBsaXN0KHJhdGUgPSAxL3NpZ21hKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSAibGlnaHRibHVlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5ldHlwZT0xLHNpemU9MC4xLGFscGhhID0gMC4yKSB9KSArCiAgc3RhdF9mdW5jdGlvbihmdW49ZGV4cCxhcmdzPWxpc3QocmF0ZSA9IDEvc2lnbWFfZnJvbXNpZ21hMl9OQyksIGxpbmV0eXBlPTIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyhjb2xvcj0iTWlncmFpbmVfU2lnbWEyIiksIHNob3cubGVnZW5kID0gVCkgKwogIHN0YXRfZnVuY3Rpb24oZnVuPWRleHAsYXJncz1saXN0KHJhdGUgPSAxL3NpZ21hX2Zyb21OU19OQyksIGxpbmV0eXBlPTIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyhjb2xvcj0iTWlncmFpbmVfTmVpZ2hib3Job29kX1NpemUiKSwgc2hvdy5sZWdlbmQgPSBUKSArCiAgc3RhdF9mdW5jdGlvbihmdW49ZGV4cCxhcmdzPWxpc3QocmF0ZSA9IDEvc2lnbWFfZnJvbU5TX2FsbF9OQyksIGxpbmV0eXBlPTIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyhjb2xvcj0iTWlncmFpbmVfTmVpZ2hib3Job29kX1NpemVfT25lUG9wIiksIHNob3cubGVnZW5kID0gVCkgKwogIHhsYWIoIkFsb25nc2hvcmUgRGlzdGFuY2UgKGttKSIpICsgeWxhYigiRGlzcGVyc2FsIHByb2JhYmlsaXR5IGRlbnNpdHkiKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKCJLZXJuZWwiLHZhbHVlcyA9IAogICAgICAgICAgICAgICAgICAgIGMoTWlncmFpbmVfU2lnbWEyPSJkYXJrYmx1ZSIsIAogICAgICAgICAgICAgICAgICAgIE1pZ3JhaW5lX05laWdoYm9yaG9vZF9TaXplID0iYmx1ZSIsCiAgICAgICAgICAgICAgICAgICAgTWlncmFpbmVfTmVpZ2hib3Job29kX1NpemVfT25lUG9wID0gImRhcmtjeWFuIikpICsKICB5bGltKDAsMC4wMSkgCgoKa2VybmVscGxvdF9OQwpgYGAKCiMgRmlqaQoKIyMgVHJhZGl0aW9uYWwgSXNvbGF0aW9uIGJ5IERpc3RhbmNlIE1ldGhvZAoKQmFzZWQgb24gdGhlIE9HIFtAcm91c3NldEdlbmV0aWNEaWZmZXJlbnRpYXRpb25Fc3RpbWF0aW9uMTk5N10gZXN0aW1hdG9yIGZyb20gc2xvcGUgb2YgdGhlIElCRCByZWdyZXNzaW9uLgoKIyMjIENhbGN1bGF0ZSBkaXN0YW5jZSBtYXRyaWNlcwoKV2VpciBhbmQgQ29ja2VyaGFtJ3MgRnN0IGFuZCBvdGhlciBiYXNpYyBzdGF0cy4gIAoKYGBge3IgRlNUX0Zpaml9CgpEYXJ1YW51cy5GaWppLmhmc3QgPC0gZ2VuaW5kMmhpZXJmc3RhdChEYXJ1YW51cy5GaWppKQpEYXJ1YW51cy5GaWppLmxvY2kgPC0gZ2VuaW5kMmxvY2koRGFydWFudXMuRmlqaSkKI2dlbi5sb2NpIDwtIGdlbmluZDJsb2NpKGdlbikKc3RhdHMuRmlqaSA8LSBiYXNpYy5zdGF0cyhEYXJ1YW51cy5GaWppKQp0aGV0YS5GaWppIDwtIHRoZXRhLm1zYXQoRGFydWFudXMuRmlqaS5sb2NpKQojbWVhbiB0aGV0YQptZWFuKHRoZXRhLkZpamlbLDJdKQpmc3QuRmlqaSA8LSBnZW5ldC5kaXN0KERhcnVhbnVzLkZpamkuaGZzdCwgbWV0aG9kID0gIldDODQiKQojIG1lYW4gRmlzIHZhbHVlcwpzdGF0cy5GaWppJEZpcyAlPiUgYXNfdGliYmxlKCkgJT4lIHN1bW1hcml6ZShhY3Jvc3MoZXZlcnl0aGluZygpLG1lYW4sIG5hLnJtPVRSVUUpKQojIGxpbmVhcml6ZQpmc3QuRmlqaSA8LSBmc3QuRmlqaS8oMS1mc3QuRmlqaSkKYGBgCgojIyMjIyBHZW9ncmFwaGljIERpc3RhbmNlcwpBbHNvLCBnaXZlbiB0aGUgY2lyY3VsYXIgbmF0dXJlIG9mIFZpdGkgTGV2dSwgdGhlIEV1Y2xpZGVhbiBkaXN0YW5jZXMgbWVhc3VyZWQgd2l0aCBgcG9pbnREaXN0YW5jZSgpYCBhcmUgZ29pbmcgdG8gYmUgc2hvcnQuIFNvIEkgbWVhc3VyZWQgZGlzdGFuY2VzIGJldHdlZW4gZWFjaCBuZWlnaGJvcmluZyBsb2NhbGl0eSBhbG9uZyB0aGUgcmVlZiBpbiBHb29nbGUgRWFydGgsIGFzIGdpdmVuIGluIGBmaWppZGlzdGFuY2VzYAoKVGhpcyBjb2RlIGNyZWF0ZXMgYSBrbWwgZmlsZSBmb3IgaW1wb3J0IGludG8gR29vZ2xlIEVhcnRoLiAKCmBgYHtyLCBldmFsID0gVH0KZmlqaXBvcHMuc3A8LWZpamlwb3BzW2MoMSwyLDMsNSw0KV0KY29vcmRpbmF0ZXMoZmlqaXBvcHMuc3ApIDwtIGMoImRlY2ltYWxMb25naXR1ZGUiLCJkZWNpbWFsTGF0aXR1ZGUiKQpwcm9qNHN0cmluZyhmaWppcG9wcy5zcCkgPC0gQ1JTKCIrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCIpCiN3cml0ZU9HUihmaWppcG9wcy5zcCwgZHNuPSJGaWppL2Zpamlwb3BzLmttbCIsIGxheWVyID0gIkRhcnVhbnVzIHNhbXBsZXMiLCBkcml2ZXIgPSAiS01MIikKYGBgCgpJIHVzZWQgdGhlc2UgcG9pbnRzIHRvIG1lYXN1cmUgZGlzdGFuY2VzIGluIEdvb2dsZSBFYXJ0aC4gVGhlIHRvdGFsIHNhbXBsZWQgbGVuZ3RoIGZyb20gT3ZhbHUgaW4gdGhlIGVhc3QgdG8gdGhlIFlhc2F3YXMgaW4gdGhlIG5vcnRod2VzdCB3YXMgYSB0b3RhbCBvZiB+NDE0a20uCgpgYGB7cn0KI2NhbGN1bGF0ZSBncmVhdCBjaXJjbGUgZGlzdGFuY2UKZ2NkaXN0c19GaWppIDwtIGFzLmRpc3QocG9pbnREaXN0YW5jZShmaWppcG9wcy5zcCwgbG9ubGF0PVQpLzEwMDApCmF0dHIoZ2NkaXN0c19GaWppLCAiTGFiZWxzIikgPC0gZmlqaXBvcHMkQWJicgpnY2Rpc3RzLm1hdF9GaWppIDwtIGFzLm1hdHJpeChnY2Rpc3RzX0ZpamkpCiN3cml0ZS5jc3YoYXMubWF0cml4KGdlbi5mc3RfRmlqaSksICJEYXJ1YW51c19saW5lYXJpemVkRnN0LmNzdiIsIHJvdy5uYW1lcyA9IEYsIHF1b3RlPUYpCiN3cml0ZS5jc3YoYXMubWF0cml4KGdjZGlzdHNfRmlqaSksICJEYXJ1YW51c19nY2Rpc3RzLmNzdiIsIHJvdy5uYW1lcyA9IEYsIHF1b3RlPUYpCgojcHVsbCBvdXQgYSBmZXcgb3RoZXIgZGlzdGFuY2VzIHdlJ2xsIG5lZWQKbmVpZ2hib3JkaXN0c19GaWppIDwtIGdjZGlzdHMubWF0X0Zpamlbcm93KGdjZGlzdHMubWF0X0ZpamkpID09IGNvbChnY2Rpc3RzLm1hdF9GaWppKSArIDFdCiNkaXN0ZnJvbVAxIDwtIGdjZGlzdHMubWF0WywxXQoKI21lYW5kaXN0cyA8LSBtZWFuKG5laWdoYm9yZGlzdHMpCmZpamlkaXN0YW5jZXMgPC0gYygoMTA2LjAzLTk4LjE2KSwgKDE1NS4yMi0xMDYuMDMpLCAoMTg4LjU4LTE1NS4yMiksICgyNzMuNTAtMTg4LjU4KSwKICAgICAgICAgICAgICAgICAgICgzNzAtMjczLjUwKSwgKDM3OC4xMy0zNzAuMCkpCgptZWFuZGlzdHNfRmlqaSA8LSBtZWFuKGZpamlkaXN0YW5jZXMpCm1heGRpc3RfRmlqaSA8LSAzNzguMTMtOTguMTYKCmZpamlkaXN0YW5jZXMKCgpgYGAKClRoaXMgZ2l2ZXMgdXMgYSBtZWFuIHNhbXBsaW5nIGRpc3RhbmNlIG9mIGByIG1lYW5kaXN0c19GaWppYAoKCiMjIyBDcmVhdGUgRGlzcGVyc2FsIEtlcm5lbAoKCiMjIyMgQ2FsY3VsYXRlIGxpbmVhciBtb2RlbAoKCmBgYHtyIElCRF9OQ30KIyBtYW50ZWwgdGVzdAptYW50ZWx0PC1tYW50ZWwucmFuZHRlc3QoZnN0LkZpamksZ2NkaXN0c19GaWppLCBucmVwZXQgPSAxMDAwMCkKCmRpc3RhbmNlcyA8LSB0aWJibGUoZGlzdGFuY2U9YXMudmVjdG9yKGdjZGlzdHNfRmlqaSksZnN0PWFzLnZlY3Rvcihmc3QuRmlqaSkpCgpsbW9kZWxfRmlqaSA8LSBsbShmc3QgfiBkaXN0YW5jZSAsIGRpc3RhbmNlcykKCnNsb3BlX0ZpamkgPC0gbG1vZGVsX0ZpamkkY29lZmZpY2llbnRzWzJdCm1hbnRlbHIgPC0gcm91bmQobWFudGVsdCRvYnMsIDIpCnB2YWx1ZSA8LSByb3VuZChtYW50ZWx0JHB2YWx1ZSwgNSkKCmxtb2RlbF9wbG90X0ZpamkgPC0gZ2dwbG90KGRpc3RhbmNlcyxhZXMoeD1kaXN0YW5jZSx5PWZzdCkpICsKICAgICAgICAgICAgICAgIGdlb21fcG9pbnQoKSArIGdlb21fc21vb3RoKG1ldGhvZD1sbSkgKyB4bGFiKCJHZW9ncmFwaGljIERpc3RhbmNlIChrbSkiKSArIAogICAgICAgICAgICAgICAgeWxhYihleHByZXNzaW9uKEZbIlNUIl0vMS1GWyJTVCJdKSkgKyAKICAgICAgICAgICAgICAgIGdlb21fdGV4dChsYWJlbCA9IHBhc3RlKCJtID0iLCByb3VuZChzbG9wZV9GaWppLDgpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI7IE1hbnRlbCByID0iLCBtYW50ZWxyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiwgcCA9IiwgcHZhbHVlICksIAogICAgICAgICAgICAgICAgICAgICAgICAgIG1hcHBpbmcgPSBhZXMoeCA9IDgwLCB5ID0gLTAuMDAyKSkKCmxtb2RlbF9wbG90X0ZpamkKCgoKI2dnc2F2ZSgiRmlqaV9JQkQucGRmIiwgcGxvdD1sbW9kZWxfcGxvdCxkZXZpY2U9InBkZiIsIHdpZHRoPTcsIGhlaWdodD01LHVuaXRzPSJpbiIpCgpgYGAKCkFuZCBhZnRlciByZW1vdmluZyB0aGUgMyB3b25reSBsb2NpLCB0aGUgc2xvcGUgaXMgdmVyeSBzbGlnaHRseSBwb3NpdGl2ZSEKCiMjIyBDYWxjdWxhdGUgRWZmZWN0aXZlIFNpemUKClB1bGwgb3V0IGp1c3QgdGhlIHJlbGV2YW50IEZpamkgZXN0aW1hdGVzIG9mIE5lLiBUaGUgbmVnYXRpdmUgbnVtYmVycyByZWZsZWN0IHZlcnkgaGlnaCB2YWx1ZXMgb2YgTmUhCgpgYGB7cn0KCk5lX2VzdGltYXRlc19GaWppIDwtIE5lX2VzdGltYXRlc19mICU+JSBmaWx0ZXIoUG9wdWxhdGlvbiAlaW4lIGZpamlwb3BzJEFiYnIpCgojCk5lX2VzdGltYXRlc19GaWppWyxjKDE6NCw4LDExLDEyKV0KCgoKIyBoYXJtb25pYyBtZWFuIG9mIE5lLCBmb2xsb3dpbmcgV2FwbGVzIGFuZCBEbyAyMDEwCk5lX2htX0ZpamkgPC0gaGFybV9tZWFuKE5lX2VzdGltYXRlc19GaWppJE5lKQpgYGAKCgojIyMgTmUgdnMuIFNhbXBsaW5nIFdpbmRvdwoKTGV0J3MgY2x1c3RlciB0aGUgc2l0ZXMgYnkgVVBHTUEgKHVzaW5nIEV1Y2xpZGVhbiBkaXN0YW5jZXMpCmBgYHtyfQpwbG90KGhjbHVzdChnY2Rpc3RzX0ZpamksImF2ZXJhZ2UiKSkKYGBgCgojIyMjIDEwa20KTGV0J3MgZXhwbG9yZSBOZSBhbmQgRmlzIHdoZW4gbHVtcGluZyBwb3B1bGF0aW9ucy4uLiAgRmlyc3QgbHVtcCBwb3B1bGF0aW9ucyB0aGF0IGFyZSBsZXNzIHRoYW4gMTAga20gYXBhcnQKCmBgYHtyfQpzdGF0cy5GaWppJEZpcyAlPiUgYXNfdGliYmxlKCkgJT4lIHN1bW1hcml6ZShhY3Jvc3MoZXZlcnl0aGluZygpLG1lYW4sIG5hLnJtPVRSVUUpKQoKRGFydWFudXMuRmlqaS4xMGttIDwtIERhcnVhbnVzLkZpamkKCkRhcnVhbnVzLkZpamkuMTBrbUBwb3AgPC0gIERhcnVhbnVzLkZpamkuMTBrbUBwb3AgJT4lIGZjdF9jb2xsYXBzZSgKICAgZWFzdCA9IGMoIlN1dmEiLCJNdWFpdiIpLAogICB3ZXN0ID0gYygiTWF0YSIsIlRhdmUiKQogKQoKRGFydWFudXMuRmlqaS4xMGttLnN0YXRzIDwtIGJhc2ljLnN0YXRzKERhcnVhbnVzLkZpamkuMTBrbSkKCkRhcnVhbnVzLkZpamkuMTBrbS5zdGF0cyRGaXMgJT4lIGFzX3RpYmJsZSgpICU+JSBzdW1tYXJpemUoYWNyb3NzKGV2ZXJ5dGhpbmcoKSxtZWFuLCBuYS5ybT1UUlVFKSkKCiNnZW5pbmRfdG9fZ2VuZXBvcChEYXJ1YW51cy5GaWppLjEwa20sb3V0cHV0ID0gIkRhcnVhbnVzL0ZpamkvRGFydWFudXNfRmlqaV8xMGttLnR4dCIpCgpOZV9lc3RpbWF0ZXNfRmlqaTEwa20gPC0gcmVhZF9OZUVzdGltYXRvcigKICAgICAgICAgICAgICAgICAgICAgICAgIk5lRXN0aW1hdG9yL0RhcnVhbnVzX0xETmVfRmlqaV8xMGtteExELnR4dCIpCk5lX2VzdGltYXRlc19GaWppMTBrbSA8LSBXREZpbHRlcihOZV9lc3RpbWF0ZXNfRmlqaTEwa20sIDEwKQoKCk5lX2htX0ZpamkxMGttIDwtIGhhcm1fbWVhbihOZV9lc3RpbWF0ZXNfRmlqaTEwa20kTmUpCgpgYGAKCiMjIyMgNDBrbSAKTm93IG1vdmUgdXAgdG8gNDAga20KYGBge3J9CkRhcnVhbnVzLkZpamkuNDBrbSA8LSBEYXJ1YW51cy5GaWppCgpEYXJ1YW51cy5GaWppLjQwa21AcG9wIDwtICBEYXJ1YW51cy5GaWppLjEwa21AcG9wICU+JSBmY3RfY29sbGFwc2UoCiAgIGVhc3QgPSBjKCJTdXZhIiwiTXVhaXYiKSwKICAgY2VudGVyID0gYygiWWFudSIsIlRhZ2EiKSwKICAgd2VzdCA9IGMoIk1hdGEiLCJUYXZlIikKICkKCkRhcnVhbnVzLkZpamkuNDBrbS5zdGF0cyA8LSBiYXNpYy5zdGF0cyhEYXJ1YW51cy5GaWppLjQwa20pCgpEYXJ1YW51cy5GaWppLjQwa20uc3RhdHMkRmlzICU+JSBhc190aWJibGUoKSAlPiUgc3VtbWFyaXplKGFjcm9zcyhldmVyeXRoaW5nKCksbWVhbiwgbmEucm09VFJVRSkpCgojZ2VuaW5kX3RvX2dlbmVwb3AoRGFydWFudXMuRmlqaS40MGttLG91dHB1dCA9ICJEYXJ1YW51cy9GaWppL0RhcnVhbnVzX0ZpamlfNDBrbS50eHQiKQoKTmVfZXN0aW1hdGVzX0Zpamk0MGttIDwtIHJlYWRfTmVFc3RpbWF0b3IoZmlsZSA9ICJOZUVzdGltYXRvci9EYXJ1YW51c19MRE5lX0ZpamlfNDBrbXhMRC50eHQiKQpOZV9lc3RpbWF0ZXNfRmlqaTQwa20gPC0gV0RGaWx0ZXIoTmVfZXN0aW1hdGVzX0Zpamk0MGttLCAxMCkKCk5lX2htX0Zpamk0MGttIDwtIGhhcm1fbWVhbihOZV9lc3RpbWF0ZXNfRmlqaTQwa20kTmUpCgoKCgpgYGAKCiMjIyMgMTAwa20KCk5vdyBtb3ZlIHVwIHRvIDEwMCBrbQpgYGB7cn0KRGFydWFudXMuRmlqaS4xMDBrbSA8LSBEYXJ1YW51cy5GaWppCgpEYXJ1YW51cy5GaWppLjEwMGttQHBvcCA8LSAgRGFydWFudXMuRmlqaS4xMDBrbUBwb3AgJT4lIGZjdF9jb2xsYXBzZSgKICAgZWFzdCA9IGMoIlN1dmEiLCJNdWFpdiIsIllhbnUiLCJUYWdhIiksCiAgIHdlc3QgPSBjKCJNYXRhIiwiVGF2ZSIsIk5hZGkiKQogKQoKRGFydWFudXMuRmlqaS4xMDBrbS5zdGF0cyA8LSBiYXNpYy5zdGF0cyhEYXJ1YW51cy5GaWppLjEwMGttKQoKRGFydWFudXMuRmlqaS4xMDBrbS5zdGF0cyRGaXMgJT4lIGFzX3RpYmJsZSgpICU+JSBzdW1tYXJpemUoYWNyb3NzKGV2ZXJ5dGhpbmcoKSxtZWFuLCBuYS5ybT1UUlVFKSkKCiNnZW5pbmRfdG9fZ2VuZXBvcChEYXJ1YW51cy5GaWppLjEwMGttLG91dHB1dCA9ICJGaWppL0RhcnVhbnVzX0ZpamlfMTAwa20udHh0IikKCk5lX2VzdGltYXRlc19GaWppMTAwa20gPC0gcmVhZF9OZUVzdGltYXRvcihmaWxlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5lRXN0aW1hdG9yL0RhcnVhbnVzX0xETmVfRmlqaV8xMDBrbXhMRC50eHQiKQpOZV9lc3RpbWF0ZXNfRmlqaTEwMGttIDwtIFdERmlsdGVyKE5lX2VzdGltYXRlc19GaWppMTAwa20sIDEwKQoKTmVfaG1fRmlqaTEwMGttIDwtIGhhcm1fbWVhbihOZV9lc3RpbWF0ZXNfRmlqaTEwMGttJE5lKQoKCgoKYGBgCgoKIyMjIyAzMDBrbQozMDBrbSAoYWxsIHBvcHMgYXMgb25lKQoKYGBge3J9Ck5lX2VzdGltYXRlc19GaWppMzAwa20gPC0gcmVhZF9OZUVzdGltYXRvcihmaWxlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5lRXN0aW1hdG9yL0RhcnVhbnVzX0xETmVfRmlqaV8xcG9weExELnR4dCIpCk5lX2VzdGltYXRlc19GaWppMzAwa20gPC0gV0RGaWx0ZXIoTmVfZXN0aW1hdGVzX0ZpamkzMDBrbSwgMTApCgoKCk5lX2htX0ZpamkzMDBrbSA8LSAyMDAwMApOZV9hbGxfRmlqaSA8LSBOZV9lc3RpbWF0ZXNfRmlqaTMwMGttJE5lCgpOZV9hbGxfRmlqaV9DSSA8LSBjKE5lX2VzdGltYXRlc19GaWppMzAwa20kUGFyYW1ldHJpY0xvdyxOZV9lc3RpbWF0ZXNfRmlqaTMwMGttJFBhcmFtZXRyaWNIaWdoKQpgYGAKCiMjIyMgRmlndXJlCgpgYGB7cn0KZmlqaXdpbmRvd3MgPC0gdGliYmxlKFNhbXBsZVdpbmRvdyA9IGMoMCwxMCw0MCwxMDAsMzAwKSwKICAgICAgICAgICAgICAgICAgICAgIGhtX05lID0gYyhOZV9obV9GaWppLE5lX2htX0ZpamkxMGttLE5lX2htX0Zpamk0MGttLE5lX2htX0ZpamkxMDBrbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZV9obV9GaWppMzAwa20pKQoKZ2dwbG90KGZpaml3aW5kb3dzLCBhZXMoeCA9IFNhbXBsZVdpbmRvdywgeSA9IGhtX05lKSkgKyBnZW9tX3BvaW50KCkgKyAKICBnZW9tX2xpbmUoKSArIHlsaW0oMCwyMDAwMCkgKyB4bGltKDAsMzAwKQpnZ3NhdmUoIkZpamlfTmVfdl9TYW1wRGlzdGFuY2UucGRmIixoZWlnaHQgPSA3LCB3aWR0aCA9IDcpCmBgYAojIyMgQ2FsY3VsYXRlIEVmZmVjdGl2ZSBEZW5zaXR5CgpgYGB7cn0KIyBEaXZpZGUgYnkgbWVhbiBkaXN0YW5jZSBiZXR3ZWVuIHNhbXBsaW5nIHNpdGVzIHRvIGdldCBkZW5zaXR5CkRlX0ZpamkgPC0gTmVfaG1fRmlqaS9tZWFuZGlzdHNfRmlqaQojRGVfYWxsX0ZpamkgPC0gTmVfYWxsX0ZpamkgLyBtYXhkaXN0X0ZpamkKYGBgCgpNZWFuIGRlbnNpdHkgaXMgYHIgRGVfRmlqaWAgaW5kaXZpZHVhbHMva20uIElmIHdlIGRvIHRoZSB3aG9sZSBzYW1wbGUgYXMgYSBzaW5nbGUgcG9wdWxhdGlvbiwgTmUgaXMgImluZmluaXRlIiBzbyB0aGlzIGlzbid0IHVzZWZ1bC4KIAojIyMgQ2FsY3VsYXRlIHNpZ21hCgpGb2xsb3dpbmcgUm91c3NldCdzIFstQHJvdXNzZXRHZW5ldGljRGlmZmVyZW50aWF0aW9uRXN0aW1hdGlvbjE5OTddIGVxdWF0aW9uOgoKJCQKXGZyYWN7MX17bX0gPSA0RF9lXHNpZ21hXjIKJCQKCldoaWNoIFtAcGluc2t5TWFyaW5lRGlzcGVyc2FsU2NhbGVzMjAxN10gcmUtYXJyYW5nZWQgdG8gZ2l2ZToKCiQkClxzaWdtYSA9IFxzcXJ0e1xmcmFjezF9ezREX2VtfX0KJCQKClNvIG5vdyBsZXQncyBwbHVnIHRoYXQgaW50byB0aGUgZmlyc3QgZXF1YXRpb24hCgpgYGB7ciBzaWdtYWZyb21TbG9wZV9GaWppfQoKc2lnbWFfZnJvbVNsb3BlX0ZpamkgPC0gc3FydCgxIC8gKDQqRGVfRmlqaSpzbG9wZV9GaWppKSkKCiNzaWdtYV9mcm9tU2xvcGVfYWxsX0ZpamkgPC0gc3FydCgxIC8gKDQqRGVfYWxsX0Zpamkqc2xvcGVfRmlqaSkpCgpgYGAKCiAkXHNpZ21hJCBlc3RpbWF0ZWQgZnJvbSB0aGlzIHNsb3BlIGlzIGByIHNpZ25pZihzaWdtYV9mcm9tU2xvcGVfRmlqaSw0KWAga20gaWYgSSB1c2UgdGhlIGhhcm1vbmljIG1lYW4gTmUgZm9yIGRlbnNpdHkuIEkgY2FuJ3QgdXNlIHRoZSBOZSBmcm9tIHRoZSB3aG9sZSBwb3B1bGF0aW9uIGJlY2F1c2UgaXQgaXMgaW5maW5pdGUuCgoKCiMjIE1pZ3JhaU5lIE1ldGhvZAoKCiMjIyBSdW5uaW5nIE1pZ3JhaU5lCgojIyMjIEZpcnN0IFJ1bgoKYGBge2Jhc2ggZXZhbCA9IEZ9CgpHZW5lcG9wRmlsZU5hbWU9Li4vRGFydWFudXNfRmlqaS50eHQKRGVtb2dyYXBoaWNNb2RlbD0gTGluZWFySUJECiNJIG1vZGlmaWVkIHRoZSBnZW5lcG9wIGZpbGUgYnkgYWRkaW5nIHNhbXBsaW5nIGNvb3JkaW5hdGVzIGFzIHRoZSBuYW1lIG9mIHRoZSAKI2xhc3QgaW5kaXZpZHVhbCBpbiBlYWNoIHBvcHVsYXRpb24uIFRoZXNlIGNvb3JkaW5hdGVzIHdlcmUgZGlzdGFuY2VzIGluIGttIAojYWxvbmcgdGhlIFZpdGkgTGV2dSByZWVmIGFuZCBjb2FzdGxpbmUgZnJvbSBPdmFsdSBpbiB0aGUgZWFzdCB0byB0aGUgWWFzYXdhcyAKI2luIHRoZSBub3J0aHdlc3Q6IGEgdG90YWwgb2YgfjQxNGttLiBJIG1lYXN1cmVkIGFsbCBkaXN0YW5jZXMgaW4gR29vZ2xlIEVhcnRoClBTT05NYXg9NDE0IDAKI05laWdoYm9yaG9vZCBzaXplIGlzIGJhc2VkIG9uIG1lYW4gZGlzdGFuY2UgYmV0d2VlbiBwb3B1bGF0aW9ucyA9IDQ2LjY2CiM0MTQvNDYuNjYgPSA4Ljg3IHNvIEkgd2lsbCB1c2UgMTAgYmlucwpHZW9CaW5OYnI9MTAKR2VvVW5pdD0gaW5kLmttCiNhbHRlcm5hdGUgd2F5IG9mIHNwZWNpZnlpbmcgdGhlIGhhYml0YXQsIG5vdCB1c2VkIGZvciBub3cKI2hhYml0YXRQYXJzPSAwLjUgMC41IDQwMCAxIDAKI2hhYml0YXRQYXJzPTAgMCAwIDMwMCAwCiNNdXRhdGlvbiBNb2RlbCBpcyBLLWFsbGVsZSA9IFBJTSwgd2l0aCBrPTIgZm9yIFNOUHMuIEdpdmVuSyBpcyBudW1iZXIgb2YgYWxsZWxlcwojIGF0IGVhY2ggbG9jdXMgKERhcnVhbnVzLkZpamlAbG9jLm4uYWxsKQpNdXRhdGlvbk1vZGVsPVBJTQpHaXZlbks9MjIsMjcsOCw0Niw0NywzMCwyNCwyMCw1MiwzMSwzOApzYW1wbGluZ1NwYWNlPSwsCnNhbXBsaW5nU2NhbGU9LCwKI0FuYWx5c2lzIC0gdGhpcyB3aWxsIGRvIDUgcnVucyBvZiAxMDAgcG9pbnRzIGFuZAojb3ZlcndyaXRlIHRob3NlIHdpdGggMTAgcnVucyBvZiAyNTAgcG9pbnRzCndyaXRlU2VxdWVuY2U9IE92ZXIsT3ZlcixPdmVyLE92ZXIsT3ZlcixBcHBlbmQsMTAKU3RhdGlzdGljU2VxdWVuY2U9UEFDClBvaW50TnVtYmVyPTEwMCwxMDAsMTAwLDEwMCwxMDAsMjUwCk5ydW5zcGVycG9pbnQ9MzAsMzAsMzAsMzAsMzAsNTAKI1dpZGUgcHJpb3JzIG9uIE5ldSwgTmVtIGFuZCBnCkxvd2VyQm91bmQ9MC4xLDEsMApVcHBlcmJvdW5kPTEsMjUwMCwxCm9uZURpbUNJPSAyTm11LCAyTm0sIE5iLCBjb25kUzIKQ29yZU5ickZvclI9NAojUGxvdHM9IGFsbDFEUHJvZmlsZXMKMURQcm9maWxlcz0yTm11LCAyTm0sIE5iLCBjb25kUzIsIGcKZXh0cmFzY2FsZT1OYj1sb2dzY2FsZQpncmFwaGljRm9ybWF0PXBkZgojd3JpdGVBZEhvY0ZpbGVzPVQKYGBgCgoKVGhpcyBydW4gY29tcGxldGVkIGluIDE0NyBtaW51dGVzCgojIyMjIFNlY29uZCBSdW4KCkEgc2Vjb25kIHJ1biB3aGVyZSBJIHdpZGVuIHRoZSBwcmlvciBvbiB0aGV0YSBhbmQgTm0uCgpgYGB7YmFzaCBldmFsID0gRn0KCkdlbmVwb3BGaWxlTmFtZT0uLi9EYXJ1YW51c19GaWppLnR4dApEZW1vZ3JhcGhpY01vZGVsPUxpbmVhcklCRAojSSBtb2RpZmllZCB0aGUgZ2VuZXBvcCBmaWxlIGJ5IGFkZGluZyBzYW1wbGluZyBjb29yZGluYXRlcyBhcyB0aGUgbmFtZSBvZiB0aGUgCiNsYXN0IGluZGl2aWR1YWwgaW4gZWFjaCBwb3B1bGF0aW9uLiBUaGVzZSBjb29yZGluYXRlcyB3ZXJlIGRpc3RhbmNlcyBpbiBrbSAKI2Fsb25nIHRoZSBWaXRpIExldnUgcmVlZiBhbmQgY29hc3RsaW5lIGZyb20gT3ZhbHUgaW4gdGhlIGVhc3QgdG8gdGhlIFlhc2F3YXMgCiNpbiB0aGUgbm9ydGh3ZXN0OiBhIHRvdGFsIG9mIH40MTRrbS4gSSBtZWFzdXJlZCBhbGwgZGlzdGFuY2VzIGluIEdvb2dsZSBFYXJ0aApQU09OTWF4PTQxNCAwCiNOZWlnaGJvcmhvb2Qgc2l6ZSBpcyBiYXNlZCBvbiBtZWFuIGRpc3RhbmNlIGJldHdlZW4gcG9wdWxhdGlvbnMgPSA0Ni42NgojNDE0LzQ2LjY2ID0gOC44NyBzbyBJIHdpbGwgdXNlIDEwIGJpbnMKR2VvQmluTmJyPTEwCkdlb1VuaXQ9IGluZC5rbQojYWx0ZXJuYXRlIHdheSBvZiBzcGVjaWZ5aW5nIHRoZSBoYWJpdGF0LCBub3QgdXNlZCBmb3Igbm93CiNoYWJpdGF0UGFycz0gMC41IDAuNSA0MDAgMSAwCiNoYWJpdGF0UGFycz0wIDAgMCAzMDAgMAojTXV0YXRpb24gTW9kZWwgaXMgSy1hbGxlbGUgPSBQSU0sIHdpdGggaz0yIGZvciBTTlBzLiBHaXZlbksgaXMgbnVtYmVyIG9mIGFsbGVsZXMKIyBhdCBlYWNoIGxvY3VzIChEYXJ1YW51cy5GaWppQGxvYy5uLmFsbCkKTXV0YXRpb25Nb2RlbD1QSU0KR2l2ZW5LPTIyLDI3LDgsNDYsNDcsMzAsMjQsMjAsNTIsMzEsMzgKc2FtcGxpbmdTcGFjZT0sLApzYW1wbGluZ1NjYWxlPSwsCiNBbmFseXNpcyAtIHRoaXMgd2lsbCBkbyA1IHJ1bnMgb2YgMTAwIHBvaW50cyBhbmQKI292ZXJ3cml0ZSB0aG9zZSB3aXRoIDEwIHJ1bnMgb2YgMjUwIHBvaW50cwp3cml0ZVNlcXVlbmNlPSBPdmVyLE92ZXIsT3ZlcixPdmVyLE92ZXIsQXBwZW5kLDEwClN0YXRpc3RpY1NlcXVlbmNlPVBBQwpQb2ludE51bWJlcj0xMDAsMTAwLDEwMCwxMDAsMTAwLDI1MApOcnVuc3BlcnBvaW50PTMwLDMwLDMwLDMwLDMwLDUwCiNXaWRlIHByaW9ycyBvbiBOZXUsIE5lbSBhbmQgZwpMb3dlckJvdW5kPTAuMSwxLDAKVXBwZXJib3VuZD0xLDI1MDAsMQpvbmVEaW1DST0gMk5tdSwgMk5tLCBOYiwgY29uZFMyCkNvcmVOYnJGb3JSPTQKI1Bsb3RzPSBhbGwxRFByb2ZpbGVzCjFEUHJvZmlsZXM9Mk5tdSwgMk5tLCBOYiwgY29uZFMyLCBnCmV4dHJhc2NhbGU9TmI9bG9nc2NhbGUKZ3JhcGhpY0Zvcm1hdD1wZGYKI3dyaXRlQWRIb2NGaWxlcz1UCmBgYAoKVGhpcyByZXN1bHQgZmluaXNoZWQgaW4gdGhlIHNhbWUgYW1vdW50IG9mIHRpbWUgYW5kIHdpdGggdmVyeSBzaW1pbGFyIHJlc3VsdHMgdG8gdGhlIGZpcnN0IQoKIyMjIyBUaGlyZCBSdW4KClJlbW92aW5nIDMgbG9jaSBhbmQgdXNpbmcgdGhlIGNvbmRTMiBzZWFyY2ggcGFyYW1ldGVyaXphdGlvbgoKYGBge2Jhc2ggZXZhbD1GfQpHZW5lcG9wRmlsZU5hbWU9Li4vLi4vRGFydWFudXNfRmlqaS50eHQKRGVtb2dyYXBoaWNNb2RlbD1MaW5lYXJJQkQKI0kgbW9kaWZpZWQgdGhlIGdlbmVwb3AgZmlsZSBieSBhZGRpbmcgc2FtcGxpbmcgY29vcmRpbmF0ZXMgYXMgdGhlIG5hbWUgb2YgdGhlIAojbGFzdCBpbmRpdmlkdWFsIGluIGVhY2ggcG9wdWxhdGlvbi4gVGhlc2UgY29vcmRpbmF0ZXMgd2VyZSBkaXN0YW5jZXMgaW4ga20gCiNhbG9uZyB0aGUgVml0aSBMZXZ1IHJlZWYgYW5kIGNvYXN0bGluZSBmcm9tIE92YWx1IGluIHRoZSBlYXN0IHRvIHRoZSBZYXNhd2FzIAojaW4gdGhlIG5vcnRod2VzdDogYSB0b3RhbCBvZiB+NDE0a20uIEkgbWVhc3VyZWQgYWxsIGRpc3RhbmNlcyBpbiBHb29nbGUgRWFydGgKUFNPTk1heD00MTQgMAojTmVpZ2hib3Job29kIHNpemUgaXMgYmFzZWQgb24gbWVhbiBkaXN0YW5jZSBiZXR3ZWVuIHBvcHVsYXRpb25zID0gNDYuNjYKIzQxNC80Ni42NiA9IDguODcgc28gSSB3aWxsIHVzZSAxMCBiaW5zCkdlb0Jpbk5icj0xMApHZW9Vbml0PSBpbmQua20KI2FsdGVybmF0ZSB3YXkgb2Ygc3BlY2lmeWluZyB0aGUgaGFiaXRhdCwgbm90IHVzZWQgZm9yIG5vdwojaGFiaXRhdFBhcnM9IDAuNSAwLjUgNDAwIDEgMAojaGFiaXRhdFBhcnM9MCAwIDAgMzAwIDAKI011dGF0aW9uIE1vZGVsIGlzIEstYWxsZWxlID0gUElNLCB3aXRoIGs9MiBmb3IgU05Qcy4gR2l2ZW5LIGlzIG51bWJlciBvZiBhbGxlbGVzCiMgYXQgZWFjaCBsb2N1cyAoRGFydWFudXMuRmlqaUBsb2Mubi5hbGwpCk11dGF0aW9uTW9kZWw9UElNCkdpdmVuSz0yMiw4LDQ2LDMwLDI0LDIwLDUyLDM4CnNhbXBsaW5nU3BhY2U9LCxjb25kUzIKc2FtcGxpbmdTY2FsZT0sLGxvZ3NjYWxlCiNBbmFseXNpcyAtIHRoaXMgd2lsbCBkbyA1IHJ1bnMgb2YgMTAwIHBvaW50cyBhbmQKI292ZXJ3cml0ZSB0aG9zZSB3aXRoIDEwIHJ1bnMgb2YgMjUwIHBvaW50cwp3cml0ZVNlcXVlbmNlPSBPdmVyLE92ZXIsT3ZlcixPdmVyLE92ZXIsQXBwZW5kLDEwClN0YXRpc3RpY1NlcXVlbmNlPVBBQwpQb2ludE51bWJlcj0xMDAsMTAwLDEwMCwxMDAsMTAwLDI1MApOcnVuc3BlcnBvaW50PTMwLDMwLDMwLDMwLDMwLDUwCiNXaWRlIHByaW9ycyBvbiBOZXUsIE5lbSBhbmQgZwpMb3dlckJvdW5kPTAuMSwxLDEKVXBwZXJib3VuZD0yLDEwMDAwLDEwMDAwMApvbmVEaW1DST0gMk5tdSwgMk5tLCBOYiwgY29uZFMyCkNvcmVOYnJGb3JSPTQKI1Bsb3RzPSBhbGwxRFByb2ZpbGVzCjFEUHJvZmlsZXM9Mk5tdSwgMk5tLCBOYiwgY29uZFMyLCBnCmV4dHJhc2NhbGU9TmI9bG9nc2NhbGUKZ3JhcGhpY0Zvcm1hdD1wZGYKd3JpdGVBZEhvY0ZpbGVzPVQKYGBgCgpGaW5pc2hlZCBpbiBgciAgNjc3Ni82MGAgbWludXRlcy4KCiMjIyBDcmVhdGUgRGlzcGVyc2FsIEtlcm5lbHMKClRoaXMgZ290IG1lIHRoZSBmb2xsb3dpbmcgZXN0aW1hdGVzLiAKCk91dHB1dCBmcm9tIHJ1biAyLgoKYGBge3IgbWlncmFpbmVfcGFyYW1ldGVyc19GaWppfQoKcnVuRGlyIDwtICIvVXNlcnMvZXJpYy9naXRodWIvSUJEX0tlcm5lbHMvRGFydWFudXMvRmlqaS9NaWdyYWluZS9ydW4zIgpyZXN1bHQgPC0gcmVhZF9taWdyYWluZShydW5EaXIpCiAgCk5TX0ZpamkgPC0gcmVzdWx0WyJOUyJdCk5TQ0lfRmlqaSA8LSBjKHJlc3VsdFsiTlNDSTEiXSxyZXN1bHRbIk5TQ0kyIl0pCk5tdV9GaWppIDwtIHJlc3VsdFsiTm11Il0KTm1fRmlqaSA8LSByZXN1bHRbIk5tIl0KZ19GaWppIDwtIHJlc3VsdFsiZyJdCmxhdHRpY2UyZ2VvZ19GaWppIDwtIHJlc3VsdFsibGF0dGljZTJnZW9nIl0KCnNpZ21hMl9GaWppIDwtIGdfdG9fc2lnbWEyKGdfRmlqaSkKc2lnbWFfZnJvbXNpZ21hMl9GaWppIDwtIHNxcnQoc2lnbWEyX0ZpamkqbGF0dGljZTJnZW9nX0ZpamkpCnNpZ21hX2Zyb21OU19GaWppIDwtIHNxcnQoTlNfRmlqaS8oNCpEZV9GaWppKSkKc2lnbWFDSV9mcm9tTlNfRmlqaSA8LSBzcXJ0KE5TQ0lfRmlqaS8oNCpEZV9GaWppKSkKCgpgYGAKClRoZSAkXHNpZ21hJCB3ZSBnZXQgIGZyb20gTmVpZ2hib3Job29kIFNpemUgJFxzaWdtYSQgaXMgYHIgc2lnbWFfZnJvbU5TX0ZpamlgLiBXZSBnZXQgYSBtdWNoIGxvd2VyIGVzdGltYXRlIGZyb20gJFxzaWdtYV4yJCwgd2l0aCAkXHNpZ21hJCA9IGByIHNpZ21hX2Zyb21zaWdtYTJfRmlqaWAKCiMjIyBDb25maWRlbmNlIEludGVydmFscwoKUHJvcGFnYXRpbmcgZXJyb3Igc29ydGEgZm9sbG93aW5nIFBpbnNreSBldCBhbC4gdGFibGUgUzIKCiMjIyMgRXJyb3IgaW4gRWZmZWN0aXZlIFNpemUKCiMjIyMjIEZvciBIYXJtb25pYyBNZWFuIE1ldGhvZAoKYGBge3IgTmVfQ0lfRmlqaX0KTmVfZXN0aW1hdGVzX0ZpamkkSmFja2tuaWZlSGlnaFt3aGljaChpcy5uYShOZV9lc3RpbWF0ZXNfRmlqaSRKYWNra25pZmVIaWdoKSldIDwtIDIwMDAwCk5lX2VzdGltYXRlc19GaWppJEphY2trbmlmZUhpZ2ggPC0gYXMubnVtZXJpYyhOZV9lc3RpbWF0ZXNfRmlqaSRKYWNra25pZmVIaWdoKQpOZV9lc3RpbWF0ZXNfRmlqaSRKYWNra25pZmVMb3cgPC0gYXMubnVtZXJpYyhOZV9lc3RpbWF0ZXNfRmlqaSRKYWNra25pZmVMb3cpCgpOZV9lcnJvcl9GaWppIDwtIE5VTEwKZm9yKG4gaW4gMToxMDAwMDApewogIGhtIDwtIGhhcm1fbWVhbihtYXBwbHkocnVuaWYsIG49MSwgCiAgICAgICAgICAgICAgICAgICBtaW49TmVfZXN0aW1hdGVzX0ZpamkkSmFja2tuaWZlTG93LAogICAgICAgICAgICAgICAgICAgbWF4PU5lX2VzdGltYXRlc19GaWppJEphY2trbmlmZUhpZ2gpKQogIE5lX2Vycm9yX0ZpamkgPC0gYyhOZV9lcnJvcl9GaWppLGhtKQp9Cm5hbWVzKE5lX2Vycm9yX0ZpamkpPC1OVUxMCgpnZ3Bsb3QoZGF0YSA9IHRpYmJsZShOZV9lcnJvcl9GaWppKSwgYWVzKHg9TmVfZXJyb3JfRmlqaSkpICsgZ2VvbV9kZW5zaXR5KCkKYGBgCgojIyMjIyBGb3IgV2hvbGUgU2FtcGxlIE1ldGhvZAoKQ2FuJ3QgZG8gdGhlIHdob2xlIHNhbXBsZSBtZXRob2QsIGJlY2F1c2UgTmUgZXN0aW1hdGUgaXMgImluZmluaXRlIgoKCiMjIyMgRXJyb3IgaW4gRWZmZWN0aXZlIERlbnNpdHkKCldpbGwgbW9kZWwgdGhlIGVycm9yIGluIGBtZWFuZGlzdGAgYXMgd2VsbC4uLgoKCmBgYHtyIERlX0NJX0Zpaml9CgpEZV9lcnJvcl9GaWppIDwtIE5lX2Vycm9yX0ZpamkvIHJub3JtVHJ1bmMoMTAwMDAwLG1lYW49bWVhbmRpc3RzX0ZpamksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZCA9IG1lYW5kaXN0c19GaWppLzEuOTYsIG1pbiA9IDFlLTEwKQoKYGBgCgojIyMjIEVycm9yIGluIFNsb3BlCgpgYGB7ciBGaWppX3Nsb3BlX2Vycm9yfQoKc2xvcGVfc2VfRmlqaSA8LSBzdW1tYXJ5KGxtb2RlbF9GaWppKSRjb2VmZmljaWVudHNbMiwyXQoKZ2dwbG90KGRhdGEgPSB0aWJibGUoeCA9IGMoMCwxZS01KSksIGFlcyh4PXgpKSArIHN0YXRfZnVuY3Rpb24oZnVuPWRub3JtVHJ1bmMsIGFyZ3MgPSBsaXN0KG1lYW4gPSBzbG9wZV9GaWppLCBzZD1zbG9wZV9zZV9GaWppLCBtaW4gPSAwKSkKCnNsb3BlX2Vycm9yX0ZpamkgPC0gcm5vcm1UcnVuYygxMDAwMDAsIG1lYW4gPSBzbG9wZV9GaWppLCBzZCA9IHNsb3BlX3NlX0ZpamksbWluID0gMWUtMTApCgpnZ3Bsb3QoZGF0YSA9IHRpYmJsZShzbG9wZV9lcnJvcl9GaWppKSwgYWVzKHg9c2xvcGVfZXJyb3JfRmlqaSkpICsgZ2VvbV9kZW5zaXR5KCkKCnNpZ21hX2Vycm9yX2Zyb21TbG9wZV9GaWppIDwtIHNxcnQoMSAvICg0KkRlX2Vycm9yX0Zpamkqc2xvcGVfZXJyb3JfRmlqaSkpCgpnZ3Bsb3QoZGF0YSA9IHRpYmJsZShzaWdtYV9lcnJvcl9mcm9tU2xvcGVfRmlqaSksIGFlcyh4PXNpZ21hX2Vycm9yX2Zyb21TbG9wZV9GaWppKSkgKwogIGdlb21fZGVuc2l0eSgpICsgeGxpbSgwLDEwMDApICArIHNjYWxlX3hfbG9nMTAoKQoKcXVhbnRpbGUoc2lnbWFfZXJyb3JfZnJvbVNsb3BlX0ZpamksIGMoMC4wMjUsIDAuOTc1KSkKCmBgYAoKIyMjIyBFcnJvciBpbiBOZWlnaGJvcmhvb2QgU2l6ZQoKVXNpbmcgYSB1bmlmb3JtIGRpc3RyaWJ1dGlvbiBpcyBvdXQgYmVjYXVzZSB0aGVyZSBpcyBjbGVhcmx5IGEgcGVha2VkIGRpc3RyaWJ1dGlvbiBpbiB0aGUgTWlncmFpbmUgb3V0cHV0LiBTbyBJIGFtIHVzaW5nIGEgcXVpY2sgZml0IHRvIGEgbG9nbm9ybWFsIGRpc3RyaWJ1dGlvbgoKIVtNaWdyYWluZV9SdW4yX05laWdoYm9yaG9vZF9UaGV0YV0oZmlndXJlcy9EYV9GaWppX05laWdoYm9yaG9vZC5qcGcpCgpgYGB7ciBOZXcgTmVpZ2hib3Job29kIFNpemUgRXJyb3IgRmlqaSB9Ck5TQ0lfRmlqaQpxbG5vcm0oYygwLjAyNSwwLjk3NSksbWVhbmxvZyA9IGxvZyhOU19GaWppKSwgc2Rsb2cgPSBsb2coMTguODkpKQpgYGAKCgpgYGB7ciBOZXcgTmVpZ2hib3Job29kIFNpemUgRXJyb3JfRmlqaSB9CgpOZWlnaGJvcmhvb2RfZXJyb3JfRmlqaSA8LSBybG5vcm1UcnVuYyhuID0gMTAwMDAwLCBtZWFubG9nID0gbG9nKE5TX0ZpamkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNkbG9nID0gbG9nKDE4Ljg5KSwgbWluID0gTlNDSV9GaWppWzFdLCBtYXggPSBOU0NJX0ZpamlbMl0pCgpnZ3Bsb3QoZGF0YSA9IHRpYmJsZShOZWlnaGJvcmhvb2RfZXJyb3JfRmlqaSksIGFlcyh4PU5laWdoYm9yaG9vZF9lcnJvcl9GaWppKSkgKyAKICBnZW9tX2RlbnNpdHkoKSArIHNjYWxlX3hfbG9nMTAoKQoKc2lnbWFfZXJyb3JfZnJvbU5TX0ZpamkgPC0gc3FydChOZWlnaGJvcmhvb2RfZXJyb3JfRmlqaS8oNCpEZV9lcnJvcl9GaWppKSkKCm5hbWVzKHNpZ21hX2Vycm9yX2Zyb21OU19GaWppKSA8LSBOVUxMCgpnZ3Bsb3QoZGF0YSA9IHRpYmJsZShzaWdtYV9lcnJvcl9mcm9tTlNfRmlqaSksIAogICAgICAgYWVzKHg9c2lnbWFfZXJyb3JfZnJvbU5TX0ZpamkpKSArCiAgICAgICBnZW9tX2RlbnNpdHkoKSArIHNjYWxlX3hfbG9nMTAoKQoKYGBgCgojIyMjIFBsb3QgRGlzcGVyc2FsIEtlcm5lbHMgCgoKYGBge3J9CgprZXJuZWxwbG90X0ZpamkgPC0gZ2dwbG90KGRhdGEuZnJhbWUoeD1jKDAsMTAwKSksYWVzKHgpKSArCiAgbWFwKC54ID0gc2FtcGxlKHNpZ21hX2Vycm9yX2Zyb21OU19GaWppLDEwMDApLCAuZiA9IGZ1bmN0aW9uKHNpZ21hKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdF9mdW5jdGlvbihmdW4gPSBkZXhwLCBhcmdzID0gbGlzdChyYXRlID0gMS9zaWdtYSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gImxpZ2h0Ymx1ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZXR5cGU9MSxzaXplPTAuMSxhbHBoYSA9IDAuMikgfSkgKwogIG1hcCgueCA9IHNhbXBsZShzaWdtYV9lcnJvcl9mcm9tU2xvcGVfRmlqaSwxMDAwKSwgLmYgPSBmdW5jdGlvbihzaWdtYSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRfZnVuY3Rpb24oZnVuID0gZGV4cCwgYXJncyA9IGxpc3QocmF0ZSA9IDEvc2lnbWEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9ICJsaWdodGdyZWVuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5ldHlwZT0xLHNpemU9MC4xLGFscGhhID0gMC4yKSB9KSArCiAgc3RhdF9mdW5jdGlvbihmdW49ZGV4cCxhcmdzPWxpc3QocmF0ZSA9IDEvc2lnbWFfZnJvbVNsb3BlX0ZpamkpLCBsaW5ldHlwZT0yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoY29sb3I9IklCRF9TbG9wZSIpLCBzaG93LmxlZ2VuZCA9IFQpICsKICBzdGF0X2Z1bmN0aW9uKGZ1bj1kZXhwLGFyZ3M9bGlzdChyYXRlID0gMS9zaWdtYV9mcm9tc2lnbWEyX0ZpamkpLCBsaW5ldHlwZT0yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoY29sb3I9Ik1pZ3JhaW5lX1NpZ21hMiIpLCBzaG93LmxlZ2VuZCA9IFQpICsKICBzdGF0X2Z1bmN0aW9uKGZ1bj1kZXhwLGFyZ3M9bGlzdChyYXRlID0gMS9zaWdtYV9mcm9tTlNfRmlqaSksIGxpbmV0eXBlPTIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyhjb2xvcj0iTWlncmFpbmVfTmVpZ2hib3Job29kX1NpemUiKSwgc2hvdy5sZWdlbmQgPSBUKSArCiAgeGxhYigiQWxvbmdzaG9yZSBEaXN0YW5jZSAoa20pIikgKyB5bGFiKCJEaXNwZXJzYWwgcHJvYmFiaWxpdHkgZGVuc2l0eSIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwoIktlcm5lbCIsdmFsdWVzID0gCiAgICAgICAgICAgICAgICAgICAgYyhNaWdyYWluZV9TaWdtYTI9ImRhcmtibHVlIiwgCiAgICAgICAgICAgICAgICAgICAgTWlncmFpbmVfTmVpZ2hib3Job29kX1NpemUgPSJibHVlIiwKICAgICAgICAgICAgICAgICAgICBJQkRfU2xvcGUgPSAiZ3JlZW4iKSkgKwogIHlsaW0oMCwwLjA1KQoKCmtlcm5lbHBsb3RfRmlqaQpgYGAKCgpUaGUgcmVhc29uIHRoYXQgdGhlIGVycm9yIGlzIGdlbmVyYWxseSBzbWFsbGVyIHRoYW4gdGhlIGVzdGltYXRlIGlzIGJlY2F1c2UgdGhlIHVwcGVyIGJvdW5kcyBvZiBOZSBhcmUgb2Z0ZW4gdW5ib3VuZGVkLCBhbmQgdHJlYXRlZCBhcyAyMCwwMDAuCgojIFNvY2lldHkgSXNsYW5kcwoKIyMgVHJhZGl0aW9uYWwgSXNvbGF0aW9uIGJ5IERpc3RhbmNlIE1ldGhvZAoKQmFzZWQgb24gdGhlIE9HIFtAcm91c3NldEdlbmV0aWNEaWZmZXJlbnRpYXRpb25Fc3RpbWF0aW9uMTk5N10gZXN0aW1hdG9yIGZyb20gc2xvcGUgb2YgdGhlIElCRCByZWdyZXNzaW9uLgoKIyMjIENhbGN1bGF0ZSBkaXN0YW5jZSBtYXRyaWNlcwoKV2VpciBhbmQgQ29ja2VyaGFtJ3MgRnN0IGFuZCBvdGhlciBiYXNpYyBzdGF0cy4gIAoKYGBge3IgRlNUX0ZQLCBldmFsPUZ9CgpEYXJ1YW51cy5GUC5oZnN0IDwtIGdlbmluZDJoaWVyZnN0YXQoRGFydWFudXMuRlApCkRhcnVhbnVzLkZQLmxvY2kgPC0gZ2VuaW5kMmxvY2koRGFydWFudXMuRlApCiNnZW4ubG9jaSA8LSBnZW5pbmQybG9jaShnZW4pCnN0YXRzLkZQIDwtIGJhc2ljLnN0YXRzKERhcnVhbnVzLkZQKQp0aGV0YS5GUCA8LSB0aGV0YS5tc2F0KERhcnVhbnVzLkZQLmxvY2kpCiNtZWFuIHRoZXRhCm1lYW4odGhldGEuRlBbLDJdKQpmc3QuRlAgPC0gZ2VuZXQuZGlzdChEYXJ1YW51cy5GUC5oZnN0LCBtZXRob2QgPSAiV0M4NCIpCiMgbWVhbiBGaXMgdmFsdWVzCnN0YXRzLkZQJEZpcyAlPiUgYXNfdGliYmxlKCkgJT4lIHN1bW1hcml6ZShhY3Jvc3MoZXZlcnl0aGluZygpLG1lYW4sIG5hLnJtPVRSVUUpKQojIGxpbmVhcml6ZQpmc3QuRlAgPC0gZnN0LkZQLygxLWZzdC5GUCkKI3dyaXRlLmNzdihhcy5tYXRyaXgoZnN0LkZQKSwgIkRhcnVhbnVzX0ZQX2xpbmVhcml6ZWRGc3QuY3N2Iiwgcm93Lm5hbWVzID0gRiwgcXVvdGU9RikKCgpgYGAKCiMjIyMjIEdlb2dyYXBoaWMgRGlzdGFuY2VzCgpDYWxjdWxhdGUgZ3JlYXQgY2lyY2xlIGRpc3RhbmNlCgpgYGB7cn0KZ2NkaXN0c19GUCA8LSBhcy5kaXN0KHBvaW50RGlzdGFuY2UoRlBwb3BzWyxjKDUsNCldLCBsb25sYXQ9VCkvMTAwMCkKYXR0cihnY2Rpc3RzX0ZQLCAiTGFiZWxzIikgPC0gRlBwb3BzJEFiYnIKZ2NkaXN0cy5tYXRfRlAgPC0gYXMubWF0cml4KGdjZGlzdHNfRlApCmBgYAoKTm93IHRvIGZvbGxvdyB3aGF0IE1hbGluIGRpZCwgYW5kIGNyZWF0ZSBhIHByaW5jaXBhbCBjb21wb25lbnRzIGF4aXMsIGFuZCBtZWFzdXJlIGRpc3RhbmNlIGFsb25nIGl0LgoKYGBge3Igcm90YXRlfQojIGJlY2F1c2Ugd2Ugb25seSBjYXJlIGFib3V0IHRoZSB4IGF4aXMsIHdlIG5lZWQgdG8gcmVvcmRlcixzbyB0aGF0IFRldGlhcm9hIGNvbWVzIGFmdGVyIFB1bmEgYW5kIGJlZm9yZSBUZW1hZQpGUHBvcHMgPC0gRlBwb3BzW2MoMSw0LDIsMyw1KSxdCkZQcG9wcy5zcCA8LSBTcGF0aWFsUG9pbnRzRGF0YUZyYW1lKEZQcG9wc1ssYyg1LDQpXSwgZGF0YSA9IEZQcG9wcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9qNHN0cmluZyA9IENSUygiK3Byb2o9bG9uZ2xhdCAgK2RhdHVtPVdHUzg0IikpCkZQcG9wcy51dG0gPC0gc3BUcmFuc2Zvcm0oRlBwb3BzLnNwLCBDUlMoIitwcm9qPXV0bSArem9uZTU2UyArZGF0dW09V0dTODQiKSkKI2FzLmRpc3QocG9pbnREaXN0YW5jZShsb2NhbGl0aWVzLnV0bSxsYXRsb249RikvMTAwMCkKI3ByaW5jaXBhbCBjb21wb25lbnRzIHdpdGhvdXQgc2NhbGluZyBvciBjZW50ZXJpbmcsIHdlIGp1c3Qgd2FudCB0aGUgcm90YXRpb24KcGNfRlAgPC0gcHJjb21wKEZQcG9wcy51dG1AY29vcmRzLCByZXR4PVQsIHNjYWxlPUYsY2VudGVyPUYpCnBsb3QocGNfRlAkeCkKI3NldCBQQzIgYXhpcyB0byB6ZXJvCnBjMV9GUDwtY2JpbmQocGNfRlAkeFssMV0sMCkKCgpwY2Rpc3RzX0ZQIDwtIGFzLmRpc3QocG9pbnREaXN0YW5jZShwYzFfRlAsbG9ubGF0PUYpLzEwMDApCgphdHRyKHBjZGlzdHNfRlAsICJMYWJlbHMiKSA8LSBGUHBvcHMkQWJicgojd3JpdGUuY3N2KGFzLm1hdHJpeChwY2Rpc3RzKSwgIkFwZXJjdWxhX3BjZGlzdHMuY3N2Iiwgcm93Lm5hbWVzID0gVCwgcXVvdGU9RikKYGBgCgpgYGB7cn0KcGNkaXN0cy5tYXRfRlAgPC0gYXMubWF0cml4KHBjZGlzdHNfRlApCgojcHVsbCBvdXQgYSBmZXcgb3RoZXIgZGlzdGFuY2VzIHdlJ2xsIG5lZWQKbmVpZ2hib3JkaXN0c19GUCA8LSBwY2Rpc3RzLm1hdF9GUFtyb3cocGNkaXN0cy5tYXRfRlApID09IGNvbChwY2Rpc3RzLm1hdF9GUCkgKyAxXQpkaXN0ZnJvbVAxX0ZQIDwtIHBjZGlzdHMubWF0X0ZQWywxXQptYXhkaXN0X0ZQIDwtIG1heChwY2Rpc3RzLm1hdF9GUCkKbWVhbmRpc3RzX0ZQIDwtIG1lYW4obmVpZ2hib3JkaXN0c19GUCkKCgoKYGBgCgpNZWFuIHNhbXBsaW5nIGRpc3RhbmNlIGlzIGByIG1lYW5kaXN0c19GUGAga20uIEJ1dCBub3RlIHRoYXQgVGV0aWFyb2Egb2NjdXJzIG9ubHkgYSBjb3VwbGUgb2Yga2lsb21ldGVycyBmcm9tIHRoZSBNb29yZWEgcG9wdWxhdGlvbiBiZWNhdXNlIHRoZXkgYXJlIGJlaW5nIGZvcmNlZCBvbnRvIHRoZSByb3RhdGVkIFggYXhpcy4KCiMjIyBDcmVhdGUgRGlzcGVyc2FsIEtlcm5lbAoKCiMjIyMgQ2FsY3VsYXRlIGxpbmVhciBtb2RlbAoKRmlyc3QgdG8gZ2V0IHRoZSBzbG9wZSAkbSQgd2UgbmVlZCB0byBtYWtlIGEgc2ltcGxlIGxpbmVhciBtb2RlbC4gSSBkb24ndCB0aGluayBzaWduaWZpY2FuY2UgaXMgcmVhbGx5IGltcG9ydGFudCBoZXJlLCBidXQgd2UgY2FuIGNhbGN1bGF0ZSB0aGF0IHdpdGggYSBNYW50ZWwgdGVzdC4KCmBgYHtyIElCRF9GUH0KIyBtYW50ZWwgdGVzdAptYW50ZWx0PC1tYW50ZWwucmFuZHRlc3QoZnN0LkZQLHBjZGlzdHNfRlAsIG5yZXBldCA9IDEwMDAwKQoKZGlzdGFuY2VzIDwtIHRpYmJsZShkaXN0YW5jZT1hcy52ZWN0b3IocGNkaXN0c19GUCksZnN0PWFzLnZlY3Rvcihmc3QuRlApKQoKbG1vZGVsX0ZQIDwtIGxtKGZzdCB+IGRpc3RhbmNlICwgZGlzdGFuY2VzKQoKc2xvcGVfRlAgPC0gbG1vZGVsX0ZQJGNvZWZmaWNpZW50c1syXQptYW50ZWxyIDwtIHJvdW5kKG1hbnRlbHQkb2JzLCAyKQpwdmFsdWUgPC0gcm91bmQobWFudGVsdCRwdmFsdWUsIDUpCgpsbW9kZWxfcGxvdF9GUCA8LSBnZ3Bsb3QoZGlzdGFuY2VzLGFlcyh4PWRpc3RhbmNlLHk9ZnN0KSkgKwogICAgICAgICAgICAgICAgZ2VvbV9wb2ludCgpICsgZ2VvbV9zbW9vdGgobWV0aG9kPWxtKSArIHhsYWIoIkdlb2dyYXBoaWMgRGlzdGFuY2UgKGttKSIpICsgCiAgICAgICAgICAgICAgICB5bGFiKGV4cHJlc3Npb24oRlsiU1QiXS8xLUZbIlNUIl0pKSArIAogICAgICAgICAgICAgICAgZ2VvbV90ZXh0KGxhYmVsID0gcGFzdGUoIm0gPSIsIHNsb3BlX0ZQLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI7IE1hbnRlbCByID0iLCBtYW50ZWxyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiwgcCA9IiwgcHZhbHVlICksIAogICAgICAgICAgICAgICAgICAgICAgICAgIG1hcHBpbmcgPSBhZXMoeCA9IDgwLCB5ID0gLTAuMDAyKSkKCmxtb2RlbF9wbG90X0ZQCgoKCiNnZ3NhdmUoIkZQX0lCRC5wZGYiLCBwbG90PWxtb2RlbF9wbG90LGRldmljZT0icGRmIiwgd2lkdGg9NywgaGVpZ2h0PTUsdW5pdHM9ImluIikKCmBgYAoKRSB2b2lsYSwgYydlc3QgcG9zaXRpdmUhIEJ1dCBub3Qgc2lnbmlmaWNhbnRseSBzby4KCgojIyMgQ2FsY3VsYXRlIEVmZmVjdGl2ZSBTaXplCgpQdWxsIG91dCBqdXN0IHRoZSByZWxldmFudCBGUCBlc3RpbWF0ZXMgb2YgTmUuIFRoZSBuZWdhdGl2ZSBudW1iZXJzIHJlZmxlY3QgdmVyeSBoaWdoIHZhbHVlcyBvZiBOZSEKCmBgYHtyfQoKTmVfZXN0aW1hdGVzX0ZQIDwtIE5lX2VzdGltYXRlc19mICU+JSBmaWx0ZXIoUG9wdWxhdGlvbiAlaW4lIEZQcG9wcyRBYmJyKQoKIwpOZV9lc3RpbWF0ZXNfRlBbLGMoMTo0LDgsMTEsMTIpXQoKIyBoYXJtb25pYyBtZWFuIG9mIE5lLCBmb2xsb3dpbmcgV2FwbGVzIGFuZCBEbyAyMDEwCk5lX2htX0ZQIDwtIGhhcm1fbWVhbihOZV9lc3RpbWF0ZXNfRlAkTmUpCmBgYAoKIyMjIE5lIHZzLiBTYW1wbGluZyBXaW5kb3cKCkxldCdzIGNsdXN0ZXIgdGhlIHNpdGVzIGJ5IFVQR01BICh1c2luZyBFdWNsaWRlYW4gZGlzdGFuY2VzKQpgYGB7cn0KcGxvdChoY2x1c3QocGNkaXN0c19GUCwiYXZlcmFnZSIpKQpgYGAKCiMjIyMgMTBrbQpMZXQncyBleHBsb3JlIE5lIGFuZCBGaXMgd2hlbiBsdW1waW5nIHBvcHVsYXRpb25zLi4uICBGaXJzdCBsdW1wIHBvcHVsYXRpb25zIHRoYXQgYXJlIGxlc3MgdGhhbiAxMCBrbSBhcGFydAoKYGBge3J9CnN0YXRzLkZQJEZpcyAlPiUgYXNfdGliYmxlKCkgJT4lIHN1bW1hcml6ZShhY3Jvc3MoZXZlcnl0aGluZygpLG1lYW4sIG5hLnJtPVRSVUUpKQptZWFuRmlzX0ZQIDwtIHN0YXRzLkZQJEZpcyAlPiUgYXNfdGliYmxlKCkgJT4lCiAgc3VtbWFyaXplKGFjcm9zcyhldmVyeXRoaW5nKCksbWVhbiwgbmEucm09VFJVRSkpICU+JSBzdW1tYXJpemUobWVhbkZpcyA9IHJvd01lYW5zKC4pKQoKRGFydWFudXMuRlAuMTBrbSA8LSBEYXJ1YW51cy5GUAoKRGFydWFudXMuRlAuMTBrbUBwb3AgPC0gIERhcnVhbnVzLkZQLjEwa21AcG9wICU+JSBmY3RfY29sbGFwc2UoCiAgIFRlbVRldGlhID0gYygiVGV0aWEiLCJUZW0iKQogKQoKRGFydWFudXMuRlAuMTBrbS5zdGF0cyA8LSBiYXNpYy5zdGF0cyhEYXJ1YW51cy5GUC4xMGttKQoKRGFydWFudXMuRlAuMTBrbS5zdGF0cyRGaXMgJT4lIGFzX3RpYmJsZSgpICU+JSBzdW1tYXJpemUoYWNyb3NzKGV2ZXJ5dGhpbmcoKSxtZWFuLCBuYS5ybT1UUlVFKSkKCm1lYW5GaXNfRlBfMTBrbSA8LSBEYXJ1YW51cy5GUC4xMGttLnN0YXRzJEZpcyAlPiUgYXNfdGliYmxlKCkgJT4lCiAgc3VtbWFyaXplKGFjcm9zcyhldmVyeXRoaW5nKCksbWVhbiwgbmEucm09VFJVRSkpICU+JSBzdW1tYXJpemUobWVhbkZpcyA9IHJvd01lYW5zKC4pKQoKI2dlbmluZF90b19nZW5lcG9wKERhcnVhbnVzLkZQLjEwa20sb3V0cHV0ID0gIkRhcnVhbnVzL0ZQL0RhcnVhbnVzX0ZQXzEwa20udHh0IikKCk5lX2VzdGltYXRlc19GUDEwa20gPC0gcmVhZF9OZUVzdGltYXRvcigKICAgICAgICAgICAgICAgICAgICAgICAgIk5lRXN0aW1hdG9yL0RhcnVhbnVzX0xETmVfRlBfMTBrbXhMRC50eHQiKQoKTmVfZXN0aW1hdGVzX0ZQMTBrbSA8LSBXREZpbHRlcihOZV9lc3RpbWF0ZXNfRlAxMGttLCAxMCkKCgpOZV9obV9GUDEwa20gPC0gaGFybV9tZWFuKE5lX2VzdGltYXRlc19GUDEwa20kTmUpCgpgYGAKCiMjIyMgMjBrbSAKCmBgYHtyfQpEYXJ1YW51cy5GUC4yMGttIDwtIERhcnVhbnVzLkZQCgpEYXJ1YW51cy5GUC4yMGttQHBvcCA8LSAgRGFydWFudXMuRlAuMjBrbUBwb3AgJT4lIGZjdF9jb2xsYXBzZSgKICAgVGVtVGV0aWFNbyA9IGMoIlRldGlhIiwiVGVtIiwiTW8iKQogKQoKRGFydWFudXMuRlAuMjBrbS5zdGF0cyA8LSBiYXNpYy5zdGF0cyhEYXJ1YW51cy5GUC4yMGttKQoKRGFydWFudXMuRlAuMjBrbS5zdGF0cyRGaXMgJT4lIGFzX3RpYmJsZSgpICU+JSBzdW1tYXJpemUoYWNyb3NzKGV2ZXJ5dGhpbmcoKSxtZWFuLCBuYS5ybT1UUlVFKSkKCm1lYW5GaXNfRlBfMjBrbSA8LSBEYXJ1YW51cy5GUC4yMGttLnN0YXRzJEZpcyAlPiUgYXNfdGliYmxlKCkgJT4lCiAgc3VtbWFyaXplKGFjcm9zcyhldmVyeXRoaW5nKCksbWVhbiwgbmEucm09VFJVRSkpICU+JSBzdW1tYXJpemUobWVhbkZpcyA9IHJvd01lYW5zKC4pKQoKI2dlbmluZF90b19nZW5lcG9wKERhcnVhbnVzLkZQLjIwa20sb3V0cHV0ID0gIkRhcnVhbnVzL0ZQL0RhcnVhbnVzX0ZQXzIwa20udHh0IikKCk5lX2VzdGltYXRlc19GUDIwa20gPC0gcmVhZF9OZUVzdGltYXRvcihmaWxlID0gIk5lRXN0aW1hdG9yL0RhcnVhbnVzX0xETmVfRlBfMjBrbXhMRC50eHQiKQpOZV9lc3RpbWF0ZXNfRlAyMGttIDwtIFdERmlsdGVyKE5lX2VzdGltYXRlc19GUDIwa20sIDEwKQoKTmVfaG1fRlAyMGttIDwtIGhhcm1fbWVhbihOZV9lc3RpbWF0ZXNfRlAyMGttJE5lKQoKCgoKYGBgCgojIyMjIDQwa20gCk5vdyBtb3ZlIHVwIHRvIDQwIGttCmBgYHtyfQpEYXJ1YW51cy5GUC40MGttIDwtIERhcnVhbnVzLkZQCgpEYXJ1YW51cy5GUC40MGttQHBvcCA8LSAgRGFydWFudXMuRlAuNDBrbUBwb3AgJT4lIGZjdF9jb2xsYXBzZSgKICAgRWFzdCA9IGMoIlRldGlhIiwiVGVtIiwiTW8iLCJQdW5hIikKICkKCkRhcnVhbnVzLkZQLjQwa20uc3RhdHMgPC0gYmFzaWMuc3RhdHMoRGFydWFudXMuRlAuNDBrbSkKCkRhcnVhbnVzLkZQLjQwa20uc3RhdHMkRmlzICU+JSBhc190aWJibGUoKSAlPiUgc3VtbWFyaXplKGFjcm9zcyhldmVyeXRoaW5nKCksbWVhbiwgbmEucm09VFJVRSkpCgptZWFuRmlzX0ZQXzQwa20gPC0gRGFydWFudXMuRlAuNDBrbS5zdGF0cyRGaXMgJT4lIGFzX3RpYmJsZSgpICU+JQogIHN1bW1hcml6ZShhY3Jvc3MoZXZlcnl0aGluZygpLG1lYW4sIG5hLnJtPVRSVUUpKSAlPiUgc3VtbWFyaXplKG1lYW5GaXMgPSByb3dNZWFucyguKSkKCiNnZW5pbmRfdG9fZ2VuZXBvcChEYXJ1YW51cy5GUC40MGttLG91dHB1dCA9ICJEYXJ1YW51cy9GUC9EYXJ1YW51c19GUF80MGttLnR4dCIpCgpOZV9lc3RpbWF0ZXNfRlA0MGttIDwtIHJlYWRfTmVFc3RpbWF0b3IoZmlsZSA9ICJOZUVzdGltYXRvci9EYXJ1YW51c19MRE5lX0ZQXzQwa214TEQudHh0IikKTmVfZXN0aW1hdGVzX0ZQNDBrbSA8LSBXREZpbHRlcihOZV9lc3RpbWF0ZXNfRlA0MGttLCAxMCkKCk5lX2htX0ZQNDBrbSA8LSBoYXJtX21lYW4oTmVfZXN0aW1hdGVzX0ZQNDBrbSROZSkKCgoKCmBgYAoKIyMjIyAzMDBrbQoKMzAwa20gKGFsbCBwb3BzIGFzIG9uZSkKCmBgYHtyfQpOZV9lc3RpbWF0ZXNfRlAzMDBrbSA8LSByZWFkX05lRXN0aW1hdG9yKGZpbGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTmVFc3RpbWF0b3IvRGFydWFudXNfTEROZV9GUF8xcG9weExELnR4dCIpCk5lX2VzdGltYXRlc19GUDMwMGttIDwtIFdERmlsdGVyKE5lX2VzdGltYXRlc19GUDMwMGttLCAxMCkKCgoKTmVfaG1fRlAzMDBrbSA8LSBOZV9lc3RpbWF0ZXNfRlAzMDBrbSROZQpOZV9hbGxfRlAgPC0gTmVfZXN0aW1hdGVzX0ZQMzAwa20kTmUKCk5lX2FsbF9GUF9DSSA8LSBjKE5lX2VzdGltYXRlc19GUDMwMGttJFBhcmFtZXRyaWNMb3csMjAwMDApCmBgYAoKIyMjIyBGaWd1cmUKCmBgYHtyfQpGUHdpbmRvd3MgPC0gdGliYmxlKFNhbXBsZVdpbmRvdyA9IGMoMCwxMCw0MCwzMDApLAogICAgICAgICAgICAgICAgICAgICAgaG1fTmUgPSBjKE5lX2htX0ZQLE5lX2htX0ZQMTBrbSxOZV9obV9GUDQwa20sTmVfaG1fRlAzMDBrbSkpCgpGUE5ldkRpc3RhbmNlIDwtIGdncGxvdChGUHdpbmRvd3MsIGFlcyh4ID0gU2FtcGxlV2luZG93LCB5ID0gaG1fTmUpKSArIGdlb21fcG9pbnQoKSArIGdlb21fbGluZSgpICsgeWxpbSgwLDIwMDAwKSArIHhsaW0oMCwzMDApCkZQTmV2RGlzdGFuY2UKI2dnc2F2ZSgiRlBfTmVfdl9TYW1wRGlzdGFuY2UucGRmIiwgaGVpZ2h0ID0gNywgd2lkdGggPSA3KQpgYGAKCiMjIyBDYWxjdWxhdGUgRWZmZWN0aXZlIERlbnNpdHkKCmBgYHtyfQojIERpdmlkZSBieSBtZWFuIGRpc3RhbmNlIGJldHdlZW4gc2FtcGxpbmcgc2l0ZXMgdG8gZ2V0IGRlbnNpdHkKRGVfRlAgPC0gTmVfaG1fRlAvbWVhbmRpc3RzX0ZQCkRlX2FsbF9GUCA8LSBOZV9hbGxfRlAvbWF4ZGlzdF9GUAoKYGBgCgpNZWFuIGRlbnNpdHkgaW4gdGhlIFNvY2lldGllcyBpcyAgYHIgRGVfRlBgIGluZHMva20sIG9yIHJlYWxseSByZWFsbHkgbGFyZ2UgaWYgd2UgY29uc2lkZXIgdGhlIHdob2xlIHNhbXBsZSBhcyBhIHNpbmdsZSBwb3B1bGF0aW9uIGByIERlX2FsbF9GUGAKCgojIyMgQ2FsY3VsYXRlIHNpZ21hCgpGb2xsb3dpbmcgUm91c3NldCdzIFstQHJvdXNzZXRHZW5ldGljRGlmZmVyZW50aWF0aW9uRXN0aW1hdGlvbjE5OTddIGVxdWF0aW9uOgoKJCQKXGZyYWN7MX17bX0gPSA0RF9lXHNpZ21hXjIKJCQKCldoaWNoIFtAcGluc2t5TWFyaW5lRGlzcGVyc2FsU2NhbGVzMjAxN10gcmUtYXJyYW5nZWQgdG8gZ2l2ZToKCiQkClxzaWdtYSA9IFxzcXJ0e1xmcmFjezF9ezREX2VtfX0KJCQKClNvIG5vdyBsZXQncyBwbHVnIHRoYXQgaW50byB0aGUgZmlyc3QgZXF1YXRpb24hCgpgYGB7ciBzaWdtYX0KCnNpZ21hX2Zyb21TbG9wZV9GUCA8LSBzcXJ0KDEgLyAoNCpEZV9GUCpzbG9wZV9GUCkpCgpzaWdtYV9mcm9tU2xvcGVfYWxsX0ZQIDwtIHNxcnQoMSAvICg0KkRlX2FsbF9GUCpzbG9wZV9GUCkpCgpgYGAKClNvIGVmZmVjdGl2ZSBkZW5zaXR5IGlzIGByIHNpZ25pZihEZV9GUCw0KWAgaW5kaXZpZHVhbHMgcGVyIGttLCBhbmQgJFxzaWdtYSQgaXMgYHIgc2lnbmlmKHNpZ21hX2Zyb21TbG9wZV9GUCw0KWAga20gaWYgd2UgY2FsY3VsYXRlIGRlbnNpdHkgYmFzZWQgb24gaGFybW9uaWMgbWVhbiBvZiBOZSwgb3IgYHIgYHNpZ25pZihzaWdtYV9mcm9tU2xvcGVfYWxsX0ZQLDQpYCBrbSBpZiB3ZSBjYWxjdWxhdGUgaXQgYWNyb3NzIHRoZSB3aG9sZSBzYW1wbGUuCgojIyBNaWdyYWlOZSBNZXRob2QKCiMjIyBSdW5uaW5nIE1pZ3JhaU5lCgojIyMjIEZpcnN0IFJ1bgoKSSBtb2RpZmllZCB0aGUgZ2VuZXBvcCBmaWxlIGJ5IGFkZGluZyBzYW1wbGluZyBjb29yZGluYXRlcyBhcyB0aGUgbmFtZSBvZiB0aGUgCmxhc3QgaW5kaXZpZHVhbCBpbiBlYWNoIHBvcHVsYXRpb24uIFRoZXJlIGlzIG5vIGNvYXN0bGluZSBmb3IgdGhlc2Ugc2FtcGxlcywKd2hpY2ggZWFjaCBjb21lIGZyb20gZGlmZmVyZW50IGlzbGFuZHMuIEkganVzdCBtZWFzdXJlZCBmcm9tIFRhaGl0aSB0byBNYXVwaXRpCkl0J3MgNjUga20gZnJvbSB0aGUgdGlwIG9mIFRhaGl0aSBJdGkgdG8gUHVuYSwgc28gSSBhZGRlZCB0aGF0IHRvIAplYWNoIGNvb3JkaW5hdGUKCmBgYHtyfQpkaXN0ZnJvbVAxX0ZQKzY1CmBgYAoKCmBgYHtiYXNoIGV2YWwgPSBGfQpHZW5lcG9wRmlsZU5hbWU9Li4vRGFydWFudXNfRlAudHh0CkRlbW9ncmFwaGljTW9kZWw9IExpbmVhcklCRAojSSBtb2RpZmllZCB0aGUgZ2VuZXBvcCBmaWxlIGJ5IGFkZGluZyBzYW1wbGluZyBjb29yZGluYXRlcyBhcyB0aGUgbmFtZSBvZiB0aGUgCiNsYXN0IGluZGl2aWR1YWwgaW4gZWFjaCBwb3B1bGF0aW9uLiBUaGVyZSBpcyBubyBjb2FzdGxpbmUgZm9yIHRoZXNlIHNhbXBsZXMsCiMgd2hpY2ggZWFjaCBjb21lIGZyb20gZGlmZmVyZW50IGlzbGFuZHMuIEkganVzdCBtZWFzdXJlZCBmcm9tIFRhaGl0aSB0byBNYXVwaXRpCiMgSXQncyA2NSBrbSBmcm9tIHRoZSB0aXAgb2YgVGFoaXRpIEl0aSB0byBQdW5hLCBzbyBJIGFkZGVkIHRoYXQgdG8gCiMgZWFjaCBjb29yZGluYXRlLgpQU09OTWF4PTM1NSAwCiNOZWlnaGJvcmhvb2Qgc2l6ZSBpcyBiYXNlZCBvbiBtZWFuIGRpc3RhbmNlIGJldHdlZW4gcG9wdWxhdGlvbnMgPSA3NS43OAojMzU1Lzc1Ljc4ID0gNC42ODQgc28gSSB3aWxsIHVzZSA2IGJpbnMKR2VvQmluTmJyPTYKR2VvVW5pdD0gaW5kLmttCiNhbHRlcm5hdGUgd2F5IG9mIHNwZWNpZnlpbmcgdGhlIGhhYml0YXQsIG5vdCB1c2VkIGZvciBub3cKI2hhYml0YXRQYXJzPSAwLjUgMC41IDQwMCAxIDAKI2hhYml0YXRQYXJzPTAgMCAwIDMwMCAwCiNNdXRhdGlvbiBNb2RlbCBpcyBLLWFsbGVsZSA9IFBJTSwgd2l0aCBrPTIgZm9yIFNOUHMuIEdpdmVuSyBpcyBudW1iZXIgb2YgYWxsZWxlcwojIGF0IGVhY2ggbG9jdXMgKERhcnVhbnVzLkZQQGxvYy5uLmFsbCkKTXV0YXRpb25Nb2RlbD1QSU0KR2l2ZW5LPTIxLDI0LDgsMzcsNDMsMjYsMTksMTYsNDMsMzEsNDAKc2FtcGxpbmdTcGFjZT0sLApzYW1wbGluZ1NjYWxlPSwsCiNBbmFseXNpcyAtIHRoaXMgd2lsbCBkbyA1IHJ1bnMgb2YgMTAwIHBvaW50cyBhbmQKI292ZXJ3cml0ZSB0aG9zZSB3aXRoIDEwIHJ1bnMgb2YgMjUwIHBvaW50cwp3cml0ZVNlcXVlbmNlPSBPdmVyLE92ZXIsT3ZlcixPdmVyLE92ZXIsQXBwZW5kLDEwClN0YXRpc3RpY1NlcXVlbmNlPVBBQwpQb2ludE51bWJlcj0xMDAsMTAwLDEwMCwxMDAsMTAwLDI1MApOcnVuc3BlcnBvaW50PTMwLDMwLDMwLDMwLDMwLDUwCiNXaWRlIHByaW9ycyBvbiBOZXUsIE5lbSBhbmQgZwpMb3dlckJvdW5kPTAuMSwxLDAKVXBwZXJib3VuZD0yLDEwMDAwLDEKb25lRGltQ0k9IDJObXUsIDJObSwgTmIsIGNvbmRTMgpDb3JlTmJyRm9yUj00CiNQbG90cz0gYWxsMURQcm9maWxlcwoxRFByb2ZpbGVzPTJObXUsIDJObSwgTmIsIGNvbmRTMiwgZwpleHRyYXNjYWxlPU5iPWxvZ3NjYWxlCmdyYXBoaWNGb3JtYXQ9cGRmCiN3cml0ZUFkSG9jRmlsZXM9VApgYGAKCgpUaGUgZmlyc3QgcnVuIGZpbmlzaGVkIHdpdGggYW4gZXJyb3IsIGJ1dCBhIHNlY29uZCBpZGVudGljYWwgcnVuIGNvbXBsZXRlZCBpbiBgciAzMDUyLzYwYCAgbWludXRlcy4gQm90aCBydW5zIGhhZCB2ZXJ5IHNpbWlsYXIgcmVzdWx0cy4KCiMjIyMgU2Vjb25kIFJ1bgoKV2lkZW5lZCB0aGUgcHJpb3Igb24gdGhldGEgYmVjYXVzZSB0aGUgZmlyc3QgdHdvIHJ1bnMgd2VyZSBvdmVyCgoKYGBge2Jhc2h9CkdlbmVwb3BGaWxlTmFtZT0uLi9EYXJ1YW51c19GUC50eHQKRGVtb2dyYXBoaWNNb2RlbD0gTGluZWFySUJECiNJIG1vZGlmaWVkIHRoZSBnZW5lcG9wIGZpbGUgYnkgYWRkaW5nIHNhbXBsaW5nIGNvb3JkaW5hdGVzIGFzIHRoZSBuYW1lIG9mIHRoZSAKI2xhc3QgaW5kaXZpZHVhbCBpbiBlYWNoIHBvcHVsYXRpb24uIFRoZXJlIGlzIG5vIGNvYXN0bGluZSBmb3IgdGhlc2Ugc2FtcGxlcywKIyB3aGljaCBlYWNoIGNvbWUgZnJvbSBkaWZmZXJlbnQgaXNsYW5kcy4gSSBqdXN0IG1lYXN1cmVkIGZyb20gVGFoaXRpIHRvIE1hdXBpdGkKIyBJdCdzIDY1IGttIGZyb20gdGhlIHRpcCBvZiBUYWhpdGkgSXRpIHRvIFB1bmEsIHNvIEkgYWRkZWQgdGhhdCB0byAKIyBlYWNoIGNvb3JkaW5hdGUuClBTT05NYXg9MzU1IDAKI05laWdoYm9yaG9vZCBzaXplIGlzIGJhc2VkIG9uIG1lYW4gZGlzdGFuY2UgYmV0d2VlbiBwb3B1bGF0aW9ucyA9IDc1Ljc4CiMzNTUvNzUuNzggPSA0LjY4NCBzbyBJIHdpbGwgdXNlIDYgYmlucwpHZW9CaW5OYnI9NgpHZW9Vbml0PSBpbmQua20KI2FsdGVybmF0ZSB3YXkgb2Ygc3BlY2lmeWluZyB0aGUgaGFiaXRhdCwgbm90IHVzZWQgZm9yIG5vdwojaGFiaXRhdFBhcnM9IDAuNSAwLjUgNDAwIDEgMAojaGFiaXRhdFBhcnM9MCAwIDAgMzAwIDAKI011dGF0aW9uIE1vZGVsIGlzIEstYWxsZWxlID0gUElNLCB3aXRoIGs9MiBmb3IgU05Qcy4gR2l2ZW5LIGlzIG51bWJlciBvZiBhbGxlbGVzCiMgYXQgZWFjaCBsb2N1cyAoRGFydWFudXMuRlBAbG9jLm4uYWxsKQpNdXRhdGlvbk1vZGVsPVBJTQpHaXZlbks9MjEsMjQsOCwzNyw0MywyNiwxOSwxNiw0MywzMSw0MApzYW1wbGluZ1NwYWNlPSwsCnNhbXBsaW5nU2NhbGU9LCwKI0FuYWx5c2lzIC0gdGhpcyB3aWxsIGRvIDUgcnVucyBvZiAxMDAgcG9pbnRzIGFuZAojb3ZlcndyaXRlIHRob3NlIHdpdGggMTAgcnVucyBvZiAyNTAgcG9pbnRzCndyaXRlU2VxdWVuY2U9IE92ZXIsT3ZlcixPdmVyLE92ZXIsT3ZlcixBcHBlbmQsMTAKU3RhdGlzdGljU2VxdWVuY2U9UEFDClBvaW50TnVtYmVyPTEwMCwxMDAsMTAwLDEwMCwxMDAsMjUwCk5ydW5zcGVycG9pbnQ9MzAsMzAsMzAsMzAsMzAsNTAKI1dpZGUgcHJpb3JzIG9uIE5ldSwgTmVtIGFuZCBnCkxvd2VyQm91bmQ9MC4xLDEsMApVcHBlcmJvdW5kPTQsMTAwMDAsMQpvbmVEaW1DST0gMk5tdSwgMk5tLCBOYiwgY29uZFMyCkNvcmVOYnJGb3JSPTQKI1Bsb3RzPSBhbGwxRFByb2ZpbGVzCjFEUHJvZmlsZXM9Mk5tdSwgMk5tLCBOYiwgY29uZFMyLCBnCmV4dHJhc2NhbGU9TmI9bG9nc2NhbGUKZ3JhcGhpY0Zvcm1hdD1wZGYKI3dyaXRlQWRIb2NGaWxlcz1UCgoKYGBgCgoKIyMjIyBGaWZ0aCBSdW4KClJlbW92ZWQgMyBsb2NpLCB1c2VkIGNvbmRTMiBwYXJhbWV0ZXJpemF0aW9uCgpgYGB7YmFzaCBldmFsID1GfQpHZW5lcG9wRmlsZU5hbWU9Li4vLi4vRGFydWFudXNfRlAudHh0CkRlbW9ncmFwaGljTW9kZWw9IExpbmVhcklCRAojSSBtb2RpZmllZCB0aGUgZ2VuZXBvcCBmaWxlIGJ5IGFkZGluZyBzYW1wbGluZyBjb29yZGluYXRlcyBhcyB0aGUgbmFtZSBvZiB0aGUgCiNsYXN0IGluZGl2aWR1YWwgaW4gZWFjaCBwb3B1bGF0aW9uLiBUaGVyZSBpcyBubyBjb2FzdGxpbmUgZm9yIHRoZXNlIHNhbXBsZXMsCiMgd2hpY2ggZWFjaCBjb21lIGZyb20gZGlmZmVyZW50IGlzbGFuZHMuIEkganVzdCBtZWFzdXJlZCBmcm9tIFRhaGl0aSB0byBNYXVwaXRpCiMgSXQncyA2NSBrbSBmcm9tIHRoZSB0aXAgb2YgVGFoaXRpIEl0aSB0byBQdW5hLCBzbyBJIGFkZGVkIHRoYXQgdG8gCiMgZWFjaCBjb29yZGluYXRlLgpQU09OTWF4PTM1NSAwCiNOZWlnaGJvcmhvb2Qgc2l6ZSBpcyBiYXNlZCBvbiBtZWFuIGRpc3RhbmNlIGJldHdlZW4gcG9wdWxhdGlvbnMgPSA3NS43OAojMzU1Lzc1Ljc4ID0gNC42ODQgc28gSSB3aWxsIHVzZSA2IGJpbnMKR2VvQmluTmJyPTYKR2VvVW5pdD0gaW5kLmttCiNhbHRlcm5hdGUgd2F5IG9mIHNwZWNpZnlpbmcgdGhlIGhhYml0YXQsIG5vdCB1c2VkIGZvciBub3cKI2hhYml0YXRQYXJzPSAwLjUgMC41IDQwMCAxIDAKI2hhYml0YXRQYXJzPTAgMCAwIDMwMCAwCiNNdXRhdGlvbiBNb2RlbCBpcyBLLWFsbGVsZSA9IFBJTSwgd2l0aCBrPTIgZm9yIFNOUHMuIEdpdmVuSyBpcyBudW1iZXIgb2YgYWxsZWxlcwojIGF0IGVhY2ggbG9jdXMgKERhcnVhbnVzLkZQQGxvYy5uLmFsbCkKTXV0YXRpb25Nb2RlbD1QSU0KR2l2ZW5LPTIxLDgsMzcsMjYsMTksMTYsNDMsNDAKc2FtcGxpbmdTcGFjZT0sLGNvbmRTMgpzYW1wbGluZ1NjYWxlPSwsbG9nc2NhbGUKI0FuYWx5c2lzIC0gdGhpcyB3aWxsIGRvIDUgcnVucyBvZiAxMDAgcG9pbnRzIGFuZAojb3ZlcndyaXRlIHRob3NlIHdpdGggMTAgcnVucyBvZiAyNTAgcG9pbnRzCndyaXRlU2VxdWVuY2U9IE92ZXIsT3ZlcixPdmVyLE92ZXIsT3ZlcixBcHBlbmQsMTAKU3RhdGlzdGljU2VxdWVuY2U9UEFDClBvaW50TnVtYmVyPTEwMCwxMDAsMTAwLDEwMCwxMDAsMjUwCk5ydW5zcGVycG9pbnQ9MzAsMzAsMzAsMzAsMzAsNTAKI1dpZGUgcHJpb3JzIG9uIE5ldSwgTmVtIGFuZCBnCkxvd2VyQm91bmQ9MC4xLDEsMQpVcHBlcmJvdW5kPTQsMTAwMDAsMTAwMDAwCm9uZURpbUNJPSAyTm11LCAyTm0sIE5iLCBjb25kUzIsIGcKQ29yZU5ickZvclI9NApQbG90cz0gYWxsUHJvZmlsZXMKIzFEUHJvZmlsZXM9Mk5tdSwgMk5tLCBOYiwgY29uZFMyLCBnCmV4dHJhc2NhbGU9TmI9bG9nc2NhbGUKZ3JhcGhpY0Zvcm1hdD1wZGYKd3JpdGVBZEhvY0ZpbGVzPVQKYGBgCgpGaW5pc2hlZCBpbiBgciAzMzg3LzYwYCBtaW51dGVzLgoKIyMjIENyZWF0ZSBEaXNwZXJzYWwgS2VybmVscwoKIyMjIyBTaWdtYSBlc3RpbWF0ZXMKClRoaXMgZ290IG1lIHRoZSBmb2xsb3dpbmcgZXN0aW1hdGVzLiAKCk91dHB1dCBmcm9tIHJ1biA1LgoKYGBge3IgbWlncmFpbmVfcGFyYW1ldGVyc19GUF9ydW41fQoKcnVuRGlyIDwtICIvVXNlcnMvZXJpYy9naXRodWIvSUJEX0tlcm5lbHMvRGFydWFudXMvRlAvTWlncmFpbmUvcnVuNSIKcmVzdWx0IDwtIHJlYWRfbWlncmFpbmUocnVuRGlyKQogIApOU19GUCA8LSByZXN1bHRbIk5TIl0KTlNDSV9GUCA8LSBjKHJlc3VsdFsiTlNDSTEiXSxyZXN1bHRbIk5TQ0kyIl0pCk5tdV9GUCA8LSByZXN1bHRbIk5tdSJdCk5tX0ZQIDwtIHJlc3VsdFsiTm0iXQpnX0ZQIDwtIHJlc3VsdFsiZyJdCmxhdHRpY2UyZ2VvZ19GUCA8LSByZXN1bHRbImxhdHRpY2UyZ2VvZyJdCgpzaWdtYTJfRlAgPC0gZ190b19zaWdtYTIoZ19GUCkKc2lnbWFfZnJvbXNpZ21hMl9GUCA8LSBzcXJ0KHNpZ21hMl9GUCpsYXR0aWNlMmdlb2dfRlApCnNpZ21hX2Zyb21OU19GUCA8LSBzcXJ0KE5TX0ZQLyg0KkRlX0ZQKSkKc2lnbWFDSV9mcm9tTlNfRlAgPC0gc3FydChOU0NJX0ZQLyg0KkRlX0ZQKSkKCnNpZ21hX2Zyb21OU19hbGxfRlAgPC0gc3FydChOU19GUC8oNCpEZV9hbGxfRlApKQpzaWdtYUNJX2Zyb21OU19hbGxfRlAgPC0gc3FydChOU0NJX0ZQLyg0KkRlX2FsbF9GUCkpCgpgYGAKClRoZSAkXHNpZ21hJCB3ZSBnZXQgZnJvbSAkRl97U1R9JCB+IERpc3RhbmNlIGlzIGByIHNpZ21hX2Zyb21TbG9wZV9GUGAsIGFuZCBmcm9tIE5laWdoYm9yaG9vZCBTaXplICRcc2lnbWEkIGlzIGByIHNpZ21hX2Zyb21OU19GUGAuIFdlIGFnYWluIGdldCBhIGxvd2VyIGVzdGltYXRlIGZyb20gJFxzaWdtYV4yJCwgd2l0aCAkXHNpZ21hJCA9IGByIHNpZ21hX2Zyb21zaWdtYTJfRlBgCgojIyMgQ29uZmlkZW5jZSBJbnRlcnZhbHMKClByb3BhZ2F0aW5nIGVycm9yIHNvcnRhIGZvbGxvd2luZyBQaW5za3kgZXQgYWwuIHRhYmxlIFMyCgojIyMjIEVycm9yIGluIE5lCgojIyMjIyBGb3IgSGFybW9uaWMgTWVhbiBNZXRob2QKCkZvbGxvd2luZyBAcGluc2t5VXNpbmdJc29sYXRpb25EaXN0YW5jZTIwMTAgSSBhbSBnb2luZyB0byBib290c3RyYXAgYWNyb3NzIHRoZSBjb25maWRlbmNlIGludGVydmFscyBmb3IgZWFjaCBOYiBlc3RpbWF0ZS4gVW5mb3J0dW5hdGVseSwgdGhlIG5ldyBqYWNra25pZmUgbWV0aG9kIG9mIEBqb25lc0ltcHJvdmVkQ29uZmlkZW5jZUludGVydmFsczIwMTYgb2Z0ZW4gcmVzdWx0cyBpbiBpbmZpbml0ZSB1cHBlciBib3VuZHMgd2l0aCBtYXJpbmUgZGF0YS4gSSdtIGdvaW5nIHRvIHVzZSB0aGUgamFja2tuaWZlIENJcy4gSSdtIGFsc28gZ29pbmcgdG8gdXNlIGEgdW5pZm9ybSBkaXN0cmlidXRpb24gZm9yIHRoZSBlcnJvciBiZWNhdXNlIGFwcHJveGltYXRpbmcgdGhlIGVycm9yIHN0cnVjdHVyZSB3aXRoIENoaVNxIG9yIE5vcm1hbCBkaXN0cmlidXRpb25zIGlzIG5vdCBhIHNpbXBsZSB0YXNrIGFuZCBJJ20ganVzdCB0cnlpbmcgdG8gZ2V0IGEgc2tldGNoIG9mIHRoZSBlcnJvciB0byBjb21wYXJlIHdpdGggTWlncmFpTmUgYW55d2F5LiBJJ20gZ29pbmcgdG8gc2V0ICJJbmZpbml0ZSIgdmFsdWVzIGluIHRoZSB1cHBlciBDSSB0byAyMCwwMDAgc2luY2UgSSByYXJlbHkgc2VlIHVwcGVyIGJvdW5kcyB0aGF0IGhpZ2guCgpgYGB7ciBOYl9DSV9GUH0KTmVfZXN0aW1hdGVzX0ZQJEphY2trbmlmZUhpZ2hbd2hpY2goaXMubmEoTmVfZXN0aW1hdGVzX0ZQJEphY2trbmlmZUhpZ2gpKV0gPC0gMjAwMDAKTmVfZXN0aW1hdGVzX0ZQJEphY2trbmlmZUhpZ2ggPC0gYXMubnVtZXJpYyhOZV9lc3RpbWF0ZXNfRlAkSmFja2tuaWZlSGlnaCkKTmVfZXN0aW1hdGVzX0ZQJEphY2trbmlmZUxvdyA8LSBhcy5udW1lcmljKE5lX2VzdGltYXRlc19GUCRKYWNra25pZmVMb3cpCgpOZV9lcnJvcl9GUCA8LSBOVUxMCmZvcihuIGluIDE6MTAwMDAwKXsKICBobSA8LSBoYXJtX21lYW4obWFwcGx5KHJ1bmlmLCBuPTEsIAogICAgICAgICAgICAgICAgICAgbWluPU5lX2VzdGltYXRlc19GUCRKYWNra25pZmVMb3csCiAgICAgICAgICAgICAgICAgICBtYXg9TmVfZXN0aW1hdGVzX0ZQJEphY2trbmlmZUhpZ2gpKQogIE5lX2Vycm9yX0ZQIDwtIGMoTmVfZXJyb3JfRlAsaG0pCn0KbmFtZXMoTmVfZXJyb3JfRlApPC1OVUxMCgpnZ3Bsb3QoZGF0YSA9IHRpYmJsZShOZV9lcnJvcl9GUCksIGFlcyh4PU5lX2Vycm9yX0ZQKSkgKyBnZW9tX2RlbnNpdHkoKQpgYGAKCiMjIyMjIEZvciBXaG9sZSBTYW1wbGUgTWV0aG9kCgpOYWF5a2VucyBhbmQgRCdBbG9pYSBzaG93ZWQgdGhhdCB1c2luZyB0aGUgd2hvbGUgc2FtcGxlIHRvIGVzdGltYXRlIGRlbnNpdHkgZ2l2ZXMgcHJldHR5IHNpbWlsYXIgcmVzdWx0cyB0byB0aGUgaGFybW9uaWMgbWVhbiBtZXRob2QsIHNvIEknbSBhbHNvIGdvaW5nIHRvIHRyeSB0aGF0LiAKCmBgYHtyfQoKTmIgPC0gTmVfYWxsX0ZQCnIyX0ZQIDwtIE5lX2VzdGltYXRlc19GUDMwMGttJHIyCiNmcm9tIFdhcGxlcyAyMDA2IHRhYmxlIDIKZXIyX0ZQIDwtIDEvTmVfZXN0aW1hdGVzX0ZQMzAwa20kU2FtcFNpemUgKyAzLjE5L05lX2VzdGltYXRlc19GUDMwMGttJFNhbXBTaXplIF4yIApkZl9GUCA8LSBOZV9lc3RpbWF0ZXNfRlAzMDBrbSRJbmRBbGxlbGVzCgpXYXBsZXNNb25vTmUocjJfRlAgLSBlcjJfRlApCgojIHRoaXMgc2hvd3MgdGhhdCB3ZSBjYW4gZ2V0IGFwcHJveGltYXRlbHkgd2hhdCBOZUVzdGltYXRvciBnaXZlcyB1cy4uLiAKI25vdCBzdXJlIHdoeSBpdHMgbm90IGV4YWN0Li4uIG11c3QgYmUgbWlzc2luZyBzb21lIGNvcnJlY3Rpb24KckNJX0ZQIDwtIGRmX05DKnIyX0ZQIC8gKHFjaGlzcShjKDAuMDI1LDAuOTc1KSwgZGYgPSBkZl9GUCkpCldhcGxlc01vbm9OZShyQ0lfTkMgLSBlcjJfTkMpCgojYW5kIG5vdyB0byBnZXQgYW5kIHBsb3QgdGhlIGVycm9yIGRpc3RyaWJ1dGlvbgpOZV9lcnJvcl9hbGxfRlAgPC0gV2FwbGVzTW9ub05lKCgoZGZfRlAqcjJfRlApLyhyY2hpc3EoMTAwMDAwLCBkZiA9IGRmX0ZQKSkpIC0gZXIyX0ZQKQoKZ2dwbG90KGRhdGEgPSB0aWJibGUoTmVfZXJyb3JfYWxsX0ZQKSwgYWVzKHg9TmVfZXJyb3JfYWxsX0ZQKSkgKyAKICBnZW9tX2RlbnNpdHkoKSArIHhsaW0oMCwzMDAwMCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKYGBgCiMjIyMgRXJyb3IgaW4gRWZmZWN0aXZlIERlbnNpdHkKCmBgYHtyIE5lX0NJX0ZQfQoKRGVfZXJyb3JfRlAgPC0gTmVfZXJyb3JfRlAgL3Jub3JtVHJ1bmMoMTAwMDAwLCBtZWFuID0gbWVhbmRpc3RzX0ZQLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZCA9ICg2NS0xMCkvMS45NiwgbWluID0gMWUtMTApCgpEZV9lcnJvcl9hbGxfRlAgPC0gTmVfZXJyb3JfYWxsX0ZQIC8gbWF4ZGlzdF9GUAoKZ2dwbG90KGRhdGEgPSB0aWJibGUoRGVfZXJyb3JfRlApLCBhZXMoeD1EZV9lcnJvcl9GUCkpICsKICBnZW9tX2RlbnNpdHkoKSArIHhsaW0oMCwxMDAwKQoKZ2dwbG90KGRhdGEgPSB0aWJibGUoRGVfZXJyb3JfYWxsX0ZQKSwgYWVzKHg9RGVfZXJyb3JfYWxsX0ZQKSkgKwogIGdlb21fZGVuc2l0eSgpICsgeGxpbSgwLDEwMDApCgpgYGAKCiMjIyMgRXJyb3IgaW4gU2xvcGUKCmBgYHtyIEZQX3Nsb3BlX2Vycm9yfQoKc2xvcGVfc2VfRlAgPC0gc3VtbWFyeShsbW9kZWxfRlApJGNvZWZmaWNpZW50c1syLDJdCgpnZ3Bsb3QoZGF0YSA9IHRpYmJsZSh4ID0gYygxZS02LDFlLTQpKSwgYWVzKHg9eCkpICsgc3RhdF9mdW5jdGlvbihmdW49ZG5vcm1UcnVuYywgYXJncyA9IGxpc3QobWVhbiA9IHNsb3BlX0ZQLCBzZD1zbG9wZV9zZV9GUCwgbWluID0gMCkpCgpzbG9wZV9lcnJvcl9GUCA8LSBybm9ybVRydW5jKDEwMDAwMCwgbWVhbiA9IHNsb3BlX0ZQLCBzZCA9IHNsb3BlX3NlX0ZQLG1pbiA9IDFlLTEwKQoKZ2dwbG90KGRhdGEgPSB0aWJibGUoc2xvcGVfZXJyb3JfRmlqaSksIGFlcyh4PXNsb3BlX2Vycm9yX0ZpamkpKSArIGdlb21fZGVuc2l0eSgpCgpzaWdtYV9lcnJvcl9mcm9tU2xvcGVfRlAgPC0gc3FydCgxIC8gKDQqRGVfZXJyb3JfRlAqc2xvcGVfZXJyb3JfRlApKQoKc2lnbWFfZXJyb3JfZnJvbVNsb3BlX2FsbF9GUCA8LSBzcXJ0KDEgLyAoNCpEZV9lcnJvcl9hbGxfRlAqc2xvcGVfZXJyb3JfRlApKQoKZ2dwbG90KGRhdGEgPSB0aWJibGUoc2lnbWFfZXJyb3JfZnJvbVNsb3BlX0ZQKSwgYWVzKHg9c2lnbWFfZXJyb3JfZnJvbVNsb3BlX0ZQKSkgKwogIGdlb21fZGVuc2l0eSgpICsgeGxpbSgwLDEwMDApCgpnZ3Bsb3QoZGF0YSA9IHRpYmJsZShzaWdtYV9lcnJvcl9mcm9tU2xvcGVfYWxsX0ZQKSwgYWVzKHg9c2lnbWFfZXJyb3JfZnJvbVNsb3BlX2FsbF9GUCkpICsKICBnZW9tX2RlbnNpdHkoKSArIHhsaW0oMCwxMDAwKQoKcXVhbnRpbGUoc2lnbWFfZXJyb3JfZnJvbVNsb3BlX0ZQLCBjKDAuMDI1LCAwLjk3NSkpCgpgYGAKCiMjIyMgRXJyb3IgaW4gTmVpZ2hib3Job29kIFNpemUKVXNpbmcgYSB1bmlmb3JtIGRpc3RyaWJ1dGlvbiBpcyBvdXQgYmVjYXVzZSB0aGVyZSBpcyBjbGVhcmx5IGEgcGVha2VkIGRpc3RyaWJ1dGlvbiBpbiB0aGUgTWlncmFpbmUgb3V0cHV0LiBTbyBJIGFtIHVzaW5nIGEgcXVpY2sgZml0IHRvIGEgdHJ1bmNhdGVkIGxvZ25vcm1hbCBkaXN0cmlidXRpb24KCiFbTWlncmFpbmVfUnVuMl9OZWlnaGJvcmhvb2RfVGhldGFdKGZpZ3VyZXMvRGFfRlBfTmVpZ2hib3Job29kLmpwZykKCmBgYHtyIE5ldyBOZWlnaGJvcmhvb2QgU2l6ZSBFcnJvciBGUCB9Ck5TQ0lfRlAKY3VydmUoZGxub3JtKHgsIG1lYW5sb2cgPSBsb2coTlNfRlApLCBzZGxvZyA9IGxvZyg3LjkpLCBsb2cgPSBUKSkKcWxub3JtKGMoMC4wMjUsMC45NzUpLG1lYW5sb2cgPSBsb2coTlNfRlApLCBzZGxvZyA9IGxvZygyMDYuNSkpCmBgYAoKCmBgYHtyIE5ldyBOZWlnaGJvcmhvb2QgU2l6ZSBFcnJvcl9GUCB9CgpOZWlnaGJvcmhvb2RfZXJyb3JfRlAgPC0gcmxub3JtVHJ1bmMobiA9IDEwMDAwMCwgbWVhbmxvZyA9IGxvZyhOU19GUCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Rsb2cgPSBsb2coMjEwKSwgbWluID0gTlNDSV9GUFsxXSwgbWF4ID0gSW5mKQoKCmdncGxvdChkYXRhID0gdGliYmxlKE5laWdoYm9yaG9vZF9lcnJvcl9GUCksIGFlcyh4PU5laWdoYm9yaG9vZF9lcnJvcl9GUCkpICsgCiAgZ2VvbV9kZW5zaXR5KCkgKyBzY2FsZV94X2xvZzEwKCkKCnNpZ21hX2Vycm9yX2Zyb21OU19GUCA8LSBzcXJ0KE5laWdoYm9yaG9vZF9lcnJvcl9GUC8oNCpEZV9lcnJvcl9GUCkpCgpzaWdtYV9lcnJvcl9mcm9tTlNfYWxsX0ZQIDwtIHNxcnQoTmVpZ2hib3Job29kX2Vycm9yX0ZQLyg0KkRlX2Vycm9yX2FsbF9GUCkpCgpuYW1lcyhzaWdtYV9lcnJvcl9mcm9tTlNfRlApIDwtIE5VTEwKCmdncGxvdChkYXRhID0gdGliYmxlKHNpZ21hX2Vycm9yX2Zyb21OU19GUCksIAogICAgICAgYWVzKHg9c2lnbWFfZXJyb3JfZnJvbU5TX0ZQKSkgKwogICAgICAgZ2VvbV9kZW5zaXR5KCkgKyBzY2FsZV94X2xvZzEwKCkKCmBgYAoKIyMjIyBQbG90IERpc3BlcnNhbCBLZXJuZWxzIAoKCmBgYHtyfQoKa2VybmVscGxvdF9GUCA8LSBnZ3Bsb3QoZGF0YS5mcmFtZSh4PWMoMCwxMDApKSxhZXMoeCkpICsgCiAgbWFwKC54ID0gc2FtcGxlKHNpZ21hX2Vycm9yX2Zyb21OU19GUCwxMDAwKSwgLmYgPSBmdW5jdGlvbihzaWdtYSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRfZnVuY3Rpb24oZnVuID0gZGV4cCwgYXJncyA9IGxpc3QocmF0ZSA9IDEvc2lnbWEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9ICJsaWdodGJsdWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmV0eXBlPTEsc2l6ZT0wLjEsYWxwaGEgPSAwLjIpIH0pICsKICAgIG1hcCgueCA9IHNhbXBsZShzaWdtYV9lcnJvcl9mcm9tU2xvcGVfRlAsMTAwMCksIC5mID0gZnVuY3Rpb24oc2lnbWEpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0X2Z1bmN0aW9uKGZ1biA9IGRleHAsIGFyZ3MgPSBsaXN0KHJhdGUgPSAxL3NpZ21hKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSAibGlnaHRncmVlbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZXR5cGU9MSxzaXplPTAuMSxhbHBoYSA9IDAuMikgfSkgKwogIHN0YXRfZnVuY3Rpb24oZnVuPWRleHAsYXJncz1saXN0KHJhdGUgPSAxL3NpZ21hX2Zyb21TbG9wZV9GUCksIGxpbmV0eXBlPTIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyhjb2xvcj0iSUJEX1Nsb3BlIiksIHNob3cubGVnZW5kID0gVCkgKwogIHN0YXRfZnVuY3Rpb24oZnVuPWRleHAsYXJncz1saXN0KHJhdGUgPSAxL3NpZ21hX2Zyb21TbG9wZV9hbGxfRlApLCBsaW5ldHlwZT0yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoY29sb3I9IklCRF9TbG9wZV8xcG9wIiksIHNob3cubGVnZW5kID0gVCkgKwogIHN0YXRfZnVuY3Rpb24oZnVuPWRleHAsYXJncz1saXN0KHJhdGUgPSAxL3NpZ21hX2Zyb21zaWdtYTJfRlApLCBsaW5ldHlwZT0yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoY29sb3I9Ik1pZ3JhaW5lX1NpZ21hMiIpLCBzaG93LmxlZ2VuZCA9IFQpICsKICBzdGF0X2Z1bmN0aW9uKGZ1bj1kZXhwLGFyZ3M9bGlzdChyYXRlID0gMS9zaWdtYV9mcm9tTlNfRlApLCBsaW5ldHlwZT0yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoY29sb3I9Ik1pZ3JhaW5lX05laWdoYm9yaG9vZF9TaXplIiksIHNob3cubGVnZW5kID0gVCkgKwogIHN0YXRfZnVuY3Rpb24oZnVuPWRleHAsYXJncz1saXN0KHJhdGUgPSAxL3NpZ21hX2Zyb21OU19hbGxfRlApLCBsaW5ldHlwZT0yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoY29sb3I9Ik1pZ3JhaW5lX05laWdoYm9yaG9vZF9TaXplXzFwb3AiKSwgc2hvdy5sZWdlbmQgPSBUKSArCiAgeGxhYigiQWxvbmdzaG9yZSBEaXN0YW5jZSAoa20pIikgKyB5bGFiKCJEaXNwZXJzYWwgcHJvYmFiaWxpdHkgZGVuc2l0eSIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwoIktlcm5lbCIsdmFsdWVzID0gCiAgICAgICAgICAgICAgICAgICAgYyhJQkRfU2xvcGUgPSAiZ3JlZW4iLAogICAgICAgICAgICAgICAgICAgICAgSUJEX1Nsb3BlXzFwb3AgPSAiZGFya2dyZWVuIiwKICAgICAgICAgICAgICAgICAgICAgIE1pZ3JhaW5lX1NpZ21hMj0iZGFya2JsdWUiLCAKICAgICAgICAgICAgICAgICAgICBNaWdyYWluZV9OZWlnaGJvcmhvb2RfU2l6ZSA9ImJsdWUiLAogICAgICAgICAgICAgICAgICAgIE1pZ3JhaW5lX05laWdoYm9yaG9vZF9TaXplXzFwb3AgPSAiY3lhbjQiKSkgKwogIHlsaW0oMCwwLjEpCgoKa2VybmVscGxvdF9GUApgYGAKCiMgQ29tcGFyaW5nIEFjcm9zcyBBcmNoaXBlbGFnb3MKCmBgYHtyfQoKTkMgPC0gdGliYmxlKEFyY2hpcGVsYWdvID0gIk5ldyBDYWxlZG9uaWEiLAogICAgICAgICAgICBFc3RpbWF0ZSA9IGMoIk1lYW4gc2FtcGxpbmcgZGlzdGFuY2UiLAogICAgICAgICAgICAgICAgICAgICAgICAiRnN0IH4gRGlzdGFuY2UgU2xvcGUiLAogICAgICAgICAgICAgICAgICAgICAgICAiTmUgSGFybW9uaWMgTWVhbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICJOZSBhcyBvbmUgcG9wdWxhdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICJFZmZlY3RpdmUgRGVuc2l0eSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJFZmZlY3RpdmUgRGVuc2l0eSBvbmUgcG9wIiwKICAgICAgICAgICAgICAgICAgICAgICAgIlRoZXRhIiwKICAgICAgICAgICAgICAgICAgICAgICAgIk5tIiwKICAgICAgICAgICAgICAgICAgICAgICAgImciLAogICAgICAgICAgICAgICAgICAgICAgICAiTmVpZ2hib3Job29kIFNpemUiLAogICAgICAgICAgICAgICAgICAgICAgICAiTmVpZ2hib3Job29kIFNpemUgTG93IENJIiwKICAgICAgICAgICAgICAgICAgICAgICAgIk5laWdoYm9yaG9vZCBTaXplIEhpZ2ggQ0kiLAogICAgICAgICAgICAgICAgICAgICAgICAiQmluIFdpZHRoIiwKICAgICAgICAgICAgICAgICAgICAgICAgInNpZ21hIGZyb20gc2xvcGUiLAogICAgICAgICAgICAgICAgICAgICAgICAic2lnbWEgZnJvbSBzbG9wZTsgTmUgYXMgb25lIHBvcCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJzaWdtYSBmcm9tIE5TIiwKICAgICAgICAgICAgICAgICAgICAgICAgInNpZ21hIGZyb20gTlM7IE5lIGFzIG9uZSBwb3AiLAogICAgICAgICAgICAgICAgICAgICAgICAic2lnbWEgZnJvbSBzaWdtYTIiKSwKICAgICAgICAgICAgIFZhbHVlcyA9IGMobWVhbmRpc3RzX05DLAogICAgICAgICAgICAgICAgICAgICAgICBzbG9wZV9OQywKICAgICAgICAgICAgICAgICAgICAgICAgTmVfaG1fTkMsCiAgICAgICAgICAgICAgICAgICAgICAgIE5lX2FsbF9OQywKICAgICAgICAgICAgICAgICAgICAgICAgRGVfTkMsCiAgICAgICAgICAgICAgICAgICAgICAgIERlX2FsbF9OQywKICAgICAgICAgICAgICAgICAgICAgICAgTm11X05DLAogICAgICAgICAgICAgICAgICAgICAgICBObV9OQywKICAgICAgICAgICAgICAgICAgICAgICAgZ19OQywKICAgICAgICAgICAgICAgICAgICAgICAgTlNfTkMsCiAgICAgICAgICAgICAgICAgICAgICAgIE5TQ0lfTkNbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgIE5TQ0lfTkNbMl0sCiAgICAgICAgICAgICAgICAgICAgICAgIGxhdHRpY2UyZ2VvZ19OQywKICAgICAgICAgICAgICAgICAgICAgICAgTkEsCiAgICAgICAgICAgICAgICAgICAgICAgIE5BLAogICAgICAgICAgICAgICAgICAgICAgICBzaWdtYV9mcm9tTlNfTkMsCiAgICAgICAgICAgICAgICAgICAgICAgIHNpZ21hX2Zyb21OU19hbGxfTkMsCiAgICAgICAgICAgICAgICAgICAgICAgIHNpZ21hX2Zyb21zaWdtYTJfTkMKICAgICAgICAgICAgICAgICAgICAgICAgKSkKCkZpamkgPC0gdGliYmxlKEFyY2hpcGVsYWdvID0gIkZpamkiLAogICAgICAgICAgICBFc3RpbWF0ZSA9IGMoIk1lYW4gc2FtcGxpbmcgZGlzdGFuY2UiLAogICAgICAgICAgICAgICAgICAgICAgICAiRnN0IH4gRGlzdGFuY2UgU2xvcGUiLAogICAgICAgICAgICAgICAgICAgICAgICAiTmUgSGFybW9uaWMgTWVhbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICJOZSBhcyBvbmUgcG9wdWxhdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICJFZmZlY3RpdmUgRGVuc2l0eSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJFZmZlY3RpdmUgRGVuc2l0eSBvbmUgcG9wIiwKICAgICAgICAgICAgICAgICAgICAgICAgIlRoZXRhIiwKICAgICAgICAgICAgICAgICAgICAgICAgIk5tIiwKICAgICAgICAgICAgICAgICAgICAgICAgImciLAogICAgICAgICAgICAgICAgICAgICAgICAiTmVpZ2hib3Job29kIFNpemUiLAogICAgICAgICAgICAgICAgICAgICAgICAiTmVpZ2hib3Job29kIFNpemUgTG93IENJIiwKICAgICAgICAgICAgICAgICAgICAgICAgIk5laWdoYm9yaG9vZCBTaXplIEhpZ2ggQ0kiLAogICAgICAgICAgICAgICAgICAgICAgICAiQmluIFdpZHRoIiwKICAgICAgICAgICAgICAgICAgICAgICAgInNpZ21hIGZyb20gc2xvcGUiLAogICAgICAgICAgICAgICAgICAgICAgICAic2lnbWEgZnJvbSBzbG9wZTsgTmUgYXMgb25lIHBvcCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJzaWdtYSBmcm9tIE5TIiwKICAgICAgICAgICAgICAgICAgICAgICAgInNpZ21hIGZyb20gTlM7IE5lIGFzIG9uZSBwb3AiLAogICAgICAgICAgICAgICAgICAgICAgICAic2lnbWEgZnJvbSBzaWdtYTIiKSwKICAgICAgICAgICAgIFZhbHVlcyA9IGMobWVhbmRpc3RzX0ZpamksCiAgICAgICAgICAgICAgICAgICAgICAgIHNsb3BlX0ZpamksCiAgICAgICAgICAgICAgICAgICAgICAgIE5lX2htX0ZpamksCiAgICAgICAgICAgICAgICAgICAgICAgIE5lX2FsbF9GaWppLAogICAgICAgICAgICAgICAgICAgICAgICBEZV9GaWppLAogICAgICAgICAgICAgICAgICAgICAgICBOQSwKICAgICAgICAgICAgICAgICAgICAgICAgTm11X0ZpamksCiAgICAgICAgICAgICAgICAgICAgICAgIE5tX0ZpamksCiAgICAgICAgICAgICAgICAgICAgICAgIGdfRmlqaSwKICAgICAgICAgICAgICAgICAgICAgICAgTlNfRmlqaSwKICAgICAgICAgICAgICAgICAgICAgICAgTlNDSV9GaWppWzFdLAogICAgICAgICAgICAgICAgICAgICAgICBOU0NJX0ZpamlbMl0sCiAgICAgICAgICAgICAgICAgICAgICAgIGxhdHRpY2UyZ2VvZ19GaWppLAogICAgICAgICAgICAgICAgICAgICAgICBzaWdtYV9mcm9tU2xvcGVfRmlqaSwKICAgICAgICAgICAgICAgICAgICAgICAgTkEsCiAgICAgICAgICAgICAgICAgICAgICAgIHNpZ21hX2Zyb21OU19GaWppLAogICAgICAgICAgICAgICAgICAgICAgICBOQSwKICAgICAgICAgICAgICAgICAgICAgICAgc2lnbWFfZnJvbXNpZ21hMl9GaWppCiAgICAgICAgICAgICAgICAgICAgICAgICkpCgpGUCA8LSB0aWJibGUoQXJjaGlwZWxhZ28gPSAiU29jaWV0aWVzIiwKICAgICAgICAgICAgRXN0aW1hdGUgPSBjKCJNZWFuIHNhbXBsaW5nIGRpc3RhbmNlIiwKICAgICAgICAgICAgICAgICAgICAgICAgIkZzdCB+IERpc3RhbmNlIFNsb3BlIiwKICAgICAgICAgICAgICAgICAgICAgICAgIk5lIEhhcm1vbmljIE1lYW4iLAogICAgICAgICAgICAgICAgICAgICAgICAiTmUgYXMgb25lIHBvcHVsYXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAiRWZmZWN0aXZlIERlbnNpdHkiLAogICAgICAgICAgICAgICAgICAgICAgICAiRWZmZWN0aXZlIERlbnNpdHkgb25lIHBvcCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJUaGV0YSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJObSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJnIiwKICAgICAgICAgICAgICAgICAgICAgICAgIk5laWdoYm9yaG9vZCBTaXplIiwKICAgICAgICAgICAgICAgICAgICAgICAgIk5laWdoYm9yaG9vZCBTaXplIExvdyBDSSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJOZWlnaGJvcmhvb2QgU2l6ZSBIaWdoIENJIiwKICAgICAgICAgICAgICAgICAgICAgICAgIkJpbiBXaWR0aCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJzaWdtYSBmcm9tIHNsb3BlIiwKICAgICAgICAgICAgICAgICAgICAgICAgInNpZ21hIGZyb20gc2xvcGU7IE5lIGFzIG9uZSBwb3AiLAogICAgICAgICAgICAgICAgICAgICAgICAic2lnbWEgZnJvbSBOUyIsCiAgICAgICAgICAgICAgICAgICAgICAgICJzaWdtYSBmcm9tIE5TOyBOZSBhcyBvbmUgcG9wIiwKICAgICAgICAgICAgICAgICAgICAgICAgInNpZ21hIGZyb20gc2lnbWEyIiksCiAgICAgICAgICAgICBWYWx1ZXMgPSBjKG1lYW5kaXN0c19GUCwKICAgICAgICAgICAgICAgICAgICAgICAgc2xvcGVfRlAsCiAgICAgICAgICAgICAgICAgICAgICAgIE5lX2htX0ZQLAogICAgICAgICAgICAgICAgICAgICAgICBOZV9hbGxfRlAsCiAgICAgICAgICAgICAgICAgICAgICAgIERlX0ZQLAogICAgICAgICAgICAgICAgICAgICAgICBEZV9hbGxfRlAsCiAgICAgICAgICAgICAgICAgICAgICAgIE5tdV9GUCwKICAgICAgICAgICAgICAgICAgICAgICAgTm1fRlAsCiAgICAgICAgICAgICAgICAgICAgICAgIGdfRlAsCiAgICAgICAgICAgICAgICAgICAgICAgIE5TX0ZQLAogICAgICAgICAgICAgICAgICAgICAgICBOU0NJX0ZQWzFdLAogICAgICAgICAgICAgICAgICAgICAgICBOU0NJX0ZQWzJdLAogICAgICAgICAgICAgICAgICAgICAgICBsYXR0aWNlMmdlb2dfRlAsCiAgICAgICAgICAgICAgICAgICAgICAgIHNpZ21hX2Zyb21TbG9wZV9GUCwKICAgICAgICAgICAgICAgICAgICAgICAgc2lnbWFfZnJvbVNsb3BlX2FsbF9GUCwKICAgICAgICAgICAgICAgICAgICAgICAgc2lnbWFfZnJvbU5TX0ZQLAogICAgICAgICAgICAgICAgICAgICAgICBzaWdtYV9mcm9tTlNfYWxsX0ZQLAogICAgICAgICAgICAgICAgICAgICAgICBzaWdtYV9mcm9tc2lnbWEyX0ZQCiAgICAgICAgICAgICAgICAgICAgICAgICkpICAgICAgICAgICAgCgphY3Jvc3MuYXJjaGlwZWxhZ29zIDwtIGJpbmRfcm93cyhOQyxGaWppLEZQKQoKYWNyb3NzLmFyY2hpcGVsYWdvcy5kZiA8LSBkY2FzdChhY3Jvc3MuYXJjaGlwZWxhZ29zLEFyY2hpcGVsYWdvfkVzdGltYXRlKQoKCgojd3JpdGVfY3N2KGFjcm9zcy5hcmNoaXBlbGFnb3MuZGYsIkFjcm9zc19hcmNoaXBlbGFnb19zdGF0aXN0aWNzLmNzdiIpCiAgICAgICAKZXJyb3JzIDwtIGVuZnJhbWUoYyhOQ19OUyA9IHNpZ21hX2Vycm9yX2Zyb21OU19OQywKICAgICAgICAgICAgICAgICAgICBOQ19OU19hbGwgPSBzaWdtYV9lcnJvcl9mcm9tTlNfYWxsX05DLAogICAgICAgICAgICAgICAgICAgIEZpamlfTlMgPSBzaWdtYV9lcnJvcl9mcm9tTlNfRmlqaSwKICAgICAgICAgICAgICAgICAgICBGaWppX1Nsb3BlID0gc2lnbWFfZXJyb3JfZnJvbVNsb3BlX0ZpamksCiAgICAgICAgICAgICAgICAgICAgRlBfTlMgPSBzaWdtYV9lcnJvcl9mcm9tTlNfRlAsIAogICAgICAgICAgICAgICAgICAgIEZQX05TX2FsbCA9IHNpZ21hX2Vycm9yX2Zyb21OU19hbGxfRlAsCiAgICAgICAgICAgICAgICAgICAgRlBfU2xvcGUgPSBzaWdtYV9lcnJvcl9mcm9tU2xvcGVfRlAsCiAgICAgICAgICAgICAgICAgICAgRlBfU2xvcGVfYWxsID0gc2lnbWFfZXJyb3JfZnJvbVNsb3BlX2FsbF9GUCksCiAgICAgICAgICAgICAgICAgIG5hbWUgPSAiQXJjaGlwZWxhZ28iLCAKICAgICAgICAgICAgICAgICAgdmFsdWUgPSAiU2lnbWEiKSAlPiUgCiAgICAgICAgICAgICAgICBtdXRhdGUoQXJjaGlwZWxhZ28gPSBzdHJfcmVtb3ZlKEFyY2hpcGVsYWdvLCBwYXR0ZXJuPSJcXGQrJCIpKQoKdmlvbGlucyA8LSBnZ3Bsb3QoZXJyb3JzLCBhZXMoeCA9IEFyY2hpcGVsYWdvLCB5ID0gU2lnbWEpKSArIGdlb21fdmlvbGluKCkgKyAKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoNSwgMTAwMCkpICsgCiAgI2dlb21fcG9pbnQoZGF0YSA9IGFjcm9zcy5hcmNoaXBlbGFnb3MsIAogICMgICAgICAgICAgIG1hcHBpbmcgPSBhZXMoeCA9ICJBcmNoaXBlbGFnbyIsIHkgPSAiU2lnbWEiKSkgKwogIHNjYWxlX3lfbG9nMTAoKQoKYm94ZXMgPC0gZ2dwbG90KGVycm9ycywgYWVzKHggPSBBcmNoaXBlbGFnbywgeSA9IFNpZ21hKSkgKyBnZW9tX2JveHBsb3QoKSArIAogIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYyg1LCAxMDAwKSkgKyAKICAjZ2VvbV9wb2ludChkYXRhID0gYWNyb3NzLmFyY2hpcGVsYWdvcywgCiAgIyAgICAgICAgICAgbWFwcGluZyA9IGFlcyh4ID0gIkFyY2hpcGVsYWdvIiwgeSA9ICJTaWdtYSIpKSArCiAgc2NhbGVfeV9sb2cxMCgpCgogICAgICAgICAgCmBgYAoKIyMgTWFrZSBmaWd1cmVzIGZvciB0aGUgcHJvcG9zYWwKCmBgYHtyfQplcnJvcnMucCA8LSBlbmZyYW1lKGMoYE5ldyBDYWxlZG9uaWFgID0gc2lnbWFfZXJyb3JfZnJvbU5TX05DLAogICAgICAgICAgICAgICAgICAgIEZpamkgPSBzaWdtYV9lcnJvcl9mcm9tU2xvcGVfRmlqaSwKICAgICAgICAgICAgICAgICAgICBTb2NpZXRpZXMgPSBzaWdtYV9lcnJvcl9mcm9tU2xvcGVfRlApLAogICAgICAgICAgICAgICAgICBuYW1lID0gIkFyY2hpcGVsYWdvIiwgCiAgICAgICAgICAgICAgICAgIHZhbHVlID0gIlNpZ21hIikgJT4lIAogICAgICAgICAgICAgICAgbXV0YXRlKEFyY2hpcGVsYWdvID0gc3RyX3JlbW92ZShBcmNoaXBlbGFnbywgcGF0dGVybj0iXFxkKyQiKSkKCiNjcmVhdGUgYSB0aWJibGUgd2l0aCB0aGUgcG9pbnQgZXN0aW1hdGVzIG9mIGludGVyZXN0CnBvaW50X2VzdGltYXRlcyA8LSBhY3Jvc3MuYXJjaGlwZWxhZ29zLmRmICU+JSAgc2VsZWN0KCJBcmNoaXBlbGFnbyIsInNpZ21hIGZyb20gc2xvcGUiKSAlPiUgCiAgbXV0YXRlKGBzaWdtYSBmcm9tIHNsb3BlYCA9IHJlcGxhY2UoYHNpZ21hIGZyb20gc2xvcGVgLDIsYWNyb3NzLmFyY2hpcGVsYWdvcy5kZiRgc2lnbWEgZnJvbSBOU2BbMl0pKSAKCgp2aW9saW5zLnAgPC0gZXJyb3JzLnAgJT4lIHJlbW92ZV9taXNzaW5nKCkgJT4lIAogIG11dGF0ZShBcmNoaXBlbGFnbyA9IGZhY3RvcihBcmNoaXBlbGFnbyxsZXZlbHMgPSBjKCJOZXcgQ2FsZWRvbmlhIiwiRmlqaSIsIlNvY2lldGllcyIpKSkgJT4lIAogIGdncGxvdCgpICsgZ2VvbV92aW9saW4obWFwcGluZyA9IGFlcyh4ID0gQXJjaGlwZWxhZ28sIHkgPSBTaWdtYSkpICsgCiBnZW9tX3BvaW50KGRhdGEgPSBwb2ludF9lc3RpbWF0ZXMsIAogICAgICAgICAgICAgbWFwcGluZyA9IGFlcyh4ID0gQXJjaGlwZWxhZ28sIHkgPSBgc2lnbWEgZnJvbSBzbG9wZWApLCBjb2xvciA9ICJncmV5Iiwgc2l6ZSA9IDUpICsKICB5bGltKDAsMTAwMCkgKwogICAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKDEsIDEwMDApKSArIAogIHNjYWxlX3lfbG9nMTAoKQoKZ2dzYXZlKCJEYXJ1YW51c19hcmNoaXBlbGFnb3NfdmlvbGlucy5wZGYiLHZpb2xpbnMucCkKCgoKa2VybmVscGxvdF9hcmNoaXBlbGFnb3MgPC0gZ2dwbG90KGRhdGEuZnJhbWUoeD1jKDAsMjUwKSksYWVzKHgpKSArIAogIG1hcCgueCA9IHNhbXBsZShzaWdtYV9lcnJvcl9mcm9tTlNfTkMsNTAwKSwgLmYgPSBmdW5jdGlvbihzaWdtYSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRfZnVuY3Rpb24oZnVuID0gZGV4cCwgYXJncyA9IGxpc3QocmF0ZSA9IDEvc2lnbWEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9ICJwYWxldmlvbGV0cmVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5ldHlwZT0xLHNpemU9MC4xLGFscGhhID0gMC4xKSB9KSArCiBtYXAoLnggPSBzYW1wbGUoc2lnbWFfZXJyb3JfZnJvbVNsb3BlX0ZpamksNTAwKSwgLmYgPSBmdW5jdGlvbihzaWdtYSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdF9mdW5jdGlvbihmdW4gPSBkZXhwLCBhcmdzID0gbGlzdChyYXRlID0gMS9zaWdtYSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSAiZ29sZGVucm9kIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmV0eXBlPTEsc2l6ZT0wLjEsYWxwaGEgPSAwLjEpIH0pICsKIG1hcCgueCA9IHNhbXBsZShzaWdtYV9lcnJvcl9mcm9tU2xvcGVfRlAsNTAwKSwgLmYgPSBmdW5jdGlvbihzaWdtYSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRfZnVuY3Rpb24oZnVuID0gZGV4cCwgYXJncyA9IGxpc3QocmF0ZSA9IDEvc2lnbWEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9ICJsaWdodGJsdWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmV0eXBlPTEsc2l6ZT0wLjEsYWxwaGEgPSAwLjEpIH0pICsKICBzdGF0X2Z1bmN0aW9uKGZ1bj1kZXhwLGFyZ3M9bGlzdChyYXRlID0gMS9zaWdtYV9mcm9tTlNfTkMpLCBsaW5ldHlwZT0xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoY29sb3I9Ik5ldyBDYWxlZG9uaWEiKSwgc2hvdy5sZWdlbmQgPSBUKSArCiAgc3RhdF9mdW5jdGlvbihmdW49ZGV4cCxhcmdzPWxpc3QocmF0ZSA9IDEvc2lnbWFfZnJvbVNsb3BlX0ZpamkpLCBsaW5ldHlwZT0xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoY29sb3I9IkZpamkiKSwgc2hvdy5sZWdlbmQgPSBUKSArCiAgc3RhdF9mdW5jdGlvbihmdW49ZGV4cCxhcmdzPWxpc3QocmF0ZSA9IDEvc2lnbWFfZnJvbVNsb3BlX0ZQKSwgbGluZXR5cGU9MSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKGNvbG9yPSJTb2NpZXRpZXMiKSwgc2hvdy5sZWdlbmQgPSBUKSArCiAgeGxhYigiQWxvbmdzaG9yZSBEaXN0YW5jZSAoa20pIikgKyB5bGFiKCJEaXNwZXJzYWwgcHJvYmFiaWxpdHkgZGVuc2l0eSIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwoIkFyY2hpcGVsYWdvIix2YWx1ZXMgPSAKICAgICAgICAgICAgICAgICAgICBjKGBOZXcgQ2FsZWRvbmlhYCA9ICJyZWQiLAogICAgICAgICAgICAgICAgICAgICAgRmlqaSA9ICJvcmFuZ2UiLAogICAgICAgICAgICAgICAgICAgICAgU29jaWV0aWVzPSJibHVlIiAKICAgICAgICAgICAgICAgICAgICkpICsKICB5bGltKDAsMC4wMikKCiNnZ3NhdmUoIkRhcnVuYXVzX2FyY2hpcGVsYWdvc19rZXJuZWxzLnBkZiIsIGtlcm5lbHBsb3RfYXJjaGlwZWxhZ29zKQpgYGAK